1.什么是垃圾

1.1.所有的全局变量都不是垃圾,任何时候都有可能会用到它

1.2.如果是一个函数里的局部变量,等到该函数执行完,该变量就成了垃圾

每次执行该函数,里面产生的变量是一次性的,函数执行完就没用了,再次执行产生的是新的该变量

1.3.引用的对象判断

总结为一句:一般没有被引用的地方就是垃圾(特殊情况:环内互相引用,但切断了外部联系,也是垃圾)

1.3.1.单引用

  1. 设置被引用值为null,那么指向的那个内存就成了垃圾image.png

    1.3.2.双引用

  2. image.pnguser和admin只要有一个还在引用下面的对象,该对象就不会变成垃圾

    1.3.3.环引用image.png

  3. 使得整个环变成垃圾,设置family = null即可,只要这个环与外界没有任何联系,那么这个环就是垃圾image.png

  4. 环内使得某一项为垃圾image.png断开所有引用该对象的路线,那么该对象就是垃圾,即便它引用了别人也没用image.png

    2.如何捡垃圾(遍历和计数,只是不同的算法而已)

    2.1.标记-清除算法(英文叫:Mark-Sweep)

    image.png
    缺点:如果对象太多,那么标记会很花时间
    解决方法:

  5. Generational collection分代收集;分新生代和老一代,新生代检查频率高,老一代低

  6. Incremental collection增量收集;分批次收集,避免较大的延迟,只会有微小延迟
  7. Idle-time collection空闲时间收集;CPU空闲时尝试收集

    2.2.引用计数

    记录每个对象被引用的次数,引用一次+1,清空或删除-1,为0则回收
    优点:

  8. 没必要从根目录开始查找

  9. 可实时回收

缺点:

  1. 计数器的增减处理加重
  2. 实现繁琐,每个赋值都得替换成引用更新操作
  3. 无法回收循环引用

    3.前端的 JS 和 DOM 进程

    只删除JS 和 DOM 进程中的一个,还是不能进行垃圾回收 ```javascript var div = document.getElementById(‘xxx’) div.onclick = function(){}

setTimeout(function(){ div.remove() // 删除DOM(页面)上的div // div.onclick = null // 兼容ie div = null // JS 内存里的div为空 var div2 = document.getElementById(‘xxx’) // null console.log(div2.onclick) // error },3000) ```


参考资料:

  1. Garbage collection
  2. 几种垃圾回收算法(参考了一个计数引用)