Skip to content
On this page

什么是内存管理

内存:由可读写单元组成,表示一片可操作空间; 管理:人为的去操作一片空间的申请、使用和释放; 内存管理:开发者主动申请空间、使用空间、释放空间: 管理流程:申请、使用、释放。

JS 中不需要手动释放,引擎有垃圾回收机制;内存泄漏主要是释放环节出现问题。

垃圾回收机制

其工作内容就是查找垃圾释放空间、回收空间;算法就是工作时查找和回收所遵循的规则。 常见 GC 算法:引用计数、标记清除、标记整理、分代回收。

引用计数:设置引用数,判断当前对象上引用数是否为0 (为0 时立即回收)。 引用计数优缺点: 优点:发现垃圾时立即回收;最大限度减少程序暂停。 缺点:无法回收循环引用的对象;时间开销大。

标记清除:分标记和清除两个阶段。遍历所有对象找标记活动对象;遍历所有对象清除没有标记对象,回收相应的空间。 标记清除优缺点:解决了循环引用垃圾回收的问题;缺点是空间碎片化,浪费空间,不会立即回收垃圾对象。

标记整理:可以看做是标记清除的增强,标记阶段的操作和标记清除一致,清除阶段会先执行整理,移动对象位置(解决了空间碎片化问题)。 标记整理优缺点:减少碎片化空间;不会立即回收垃圾对象。

V8 垃圾回收策略

V8 是 JS 执行引擎,采用即时编译,内存设限(64位操作系统最大 1.5 G,32位操作系统不超过 800 MB,为什么这样设置:面对现有网页足够使用,方便使用增量垃圾回收提高效率)。

采用分代回收的算法:内存分为新生代对象和老生代对象,针对不同对象采用不同算法。 V8 中常用的 GC 算法有哪些:分代回收、空间复制、标记清除、标记整理、标记增量。

V8 如何回收新生代对象? v8 内存空间一分为二,小空间用于存储新生代对象(32M | 16M),新生代指的是存活时间较短的对象。如何回收?采用复制算法 + 标记整理,新生代内存再分为2个等大小空间,使用空间为 From ,空闲空间为 To ,活动对象存储于 From 空间,标记整理后将活动对象拷贝至 To ,From 与 To 交换空间完成释放。 回收细节:拷贝过程中可能出现“晋升”(将新生代对象移动至老生代),“晋升”如何触发:一轮 GC 还存活的新生代需要晋升,To 空间的使用率超过 25% 。

V8 如何回收老生代对象? 老生代对象存放在老生代区域,64位操作系统最大 1.4G,32位操作系统最大 700M。老生代对象是指存活时间较长的对象。 如何回收:主要使用标记清除、标记整理、增量标记算法;首先使用标记清除完成垃圾空间的回收。当不满足“晋升”时,会触发标记整理进行空间优化,还会采用增量标记进行效率优化。 新老对比:新生代区域垃圾回收使用空间换时间,老生代区域回收不适合复制算法。

增量标记如何优化垃圾回收?

Released under the MIT License.