1. 认识内存管理
不管以什么样的方式来管理内存,内存的管理都会有如下的生命周期
- 第一步:分配申请你需要的内存(申请);
- 第二步:使用分配的内存(存放一些东西,比如对象等);
- 第三步:不需要使用时,对其进行释放;
不同的编程语言对于第一步和第三步会有不同的实现:
- 手动管理内存:比如C、C++,包括早期的OC,都是需要手动来管理内存的申请和释放的(malloc和free函数);
- 自动管理内存:比如Java、JavaScript、Python、Swift、Dart等,它们有自动帮助我们管理内存;
2. JavaScript的内存管理
JS对于原始数据类型内存的分配会在执行时,直接在栈空间进行分配;
JS对于复杂数据类型内存的分配会在堆内存中
开辟一块空间,并且将这块空间的指针返回值
变量引用;
3. JavaScript的垃圾回收
垃圾回收的英文是Garbage Collection,简称GC;
常见的GC算法
- 引用计数(Reference counting)
- 当一个对象有一个引用指向它时,那么这个对象的引用就+1;
- 当一个对象的引用为0时,这个对象就可以被销毁掉;
这个算法有一个很大的弊端就是会产生循环引用
- 标记清除(mark-Sweep)
标记清除的核心思路是可达性(Reachability), 设置一个根对象(root object),垃圾回收器会定期从这个根开始,找所有从根开始有引用到的对象,对于哪些没有引用到的对象,就认为是不可用的对象;
早期js使用的就是这个算法
-
标记整理(Mark-Compact) 和“标记-清除”相似;
- 不同的是,回收期间同时会将保留的存储对象搬运汇集到连续的内存空间,从而整合空闲空间,避免内存碎片化;
分代收集(Generational collection)—— 对象被分成两组:“新的”和“旧的”。
增量收集(Incremental collection)
将垃圾收集工作分成几部分来做,然后将这几部分会逐一进行处理,这样会有许多微小的延迟而不是一个大的延迟;闲时收集(Idle-time collection)
垃圾收集器只会在 CPU 空闲时尝试运行,以减少可能对代码执行的影响。
4. V8引擎详细的内存图
V8引擎使用了多种垃圾回收算法来管理内存,其中主要使用分代收集算法,包括新生代和老生代垃圾回收。新生代垃圾回收使用复制算法和标记-清除算法,而老生代垃圾回收则使用标记-压缩算法。