我猜你连代际假说和分代回收都没听说过...

132 阅读3分钟

先抛转再引玉,思考一下几个知识点:

  1. JS 是怎么防止内存爆炸的?

  2. JS 中的 2 种常见的垃圾回收方式是什么?

  3. 代际假说的内容是什么?

  4. 分代回收具体是怎么回收的?

  5. 增量回收算法你知道多少?

先了解垃圾回收的工作流程

  • 执行垃圾回收的时机:

    1. 引擎空闲时;

    2. 内存达到阈值;

    通常由浏览器自动判断什么时候进行垃圾回收,当然在谷歌浏览器的开发者工具的 “性能” 标签可以手动触发垃圾回收,在做性能分析时比较有用。

    图片转存失败,建议将图片保存下来直接上传

  • 执行垃圾回收的步骤:

    1. 通过遍历 GC Root 中的所有对象,把无法遍历访问到的对象标记为非活动的垃圾对象;

    2. 主副垃圾回收器分别使用不同的算法对新生代内存区和老生代内存区中的非活动对象执行清除操作;

    3. 清理完成后再进行内存整理。由于垃圾对象分散在内存的各个地方,所以清理后内存区会出现很多不连续的空间(俗称内存碎片,类似下图),所以需要整理,使后续分配连续的大内存空间没问题。

      图片转存失败,建议将图片保存下来直接上传

垃圾回收中的 GC Root

  • 垃圾回收器回收的起始对象,一般是最上层对象;

  • 示例:

    1. 挂载在 window 对象上的全局对象;

    2. DOM 树;

    3. ......

垃圾回收中的标记-清除-整理算法

就下面几个大字...

  • 标记:从每一个 GC Root 开始,递归遍历这个顶层对象,遍历到的元素标记为活动对象不可回收,遍历不到的即为可回收的对象(可访问性算法);

  • 清除:将可回收的对象占用的内存空间释放;

  • 整理:将零碎的内存重新整理,不然后续不够内存分配大对象了。

垃圾回收中的主副垃圾回收器

就下面几个大字...

  • 代际假说说,大多数对象是短暂瞬间存在的,代码执行完,所有临时变量就变得无用了,这些变量由副垃圾回收器回收;

  • 全局变量、DOM 等在页面整个生命周期一直存在的内存由,主垃圾回收器回收。

牛逼的回收策略就这样,需要衡量各种场景使用不用的算法,以便有牛逼的效果。

垃圾回收中的新老生代内存区

就下面几个大字...

  • 新生代:容量小,只有几M,存放死的快的变量,被副垃圾回收器回收;

  • 老生代:容量大,存放长命百岁的大的变量,被主垃圾回收器回收;

垃圾回收中的性能优化

就下面几个大字...

  • 增量回收;

  • 并发回收;

  • 多线程回收。

完事!拜拜!后会有期!