GC定义和作用
- GC是Garbage Collection垃圾回收机制的简写
- GC可以找到内存中的垃圾、并释放和回收空间
GC里的垃圾是什么
-
程序中不再需要使用的对象
function func() { name = 'wang' return `${name} is a coder` } func()
当执行完了func之后,name变量不再需要,就可以当作垃圾被回收
-
程序中不能再访问到的对象
function func() { // 声明变量 const name = 'wang' return `${name} is a coder` } func()
当函数执行完成后,外部空间中就不能在访问name变量,就可以被当作垃圾回收
常见GC算法
- 引用计数
- 标记清除
- 标记整理
- 分代回收
引用计数算法
内存管理中,如果前者对后者有访问权限(隐式或显示访问),则说明一个对象引用另一个对象(js对象有对其原型(隐式引用)和对其属性(显示引用)的引用)
引用对象算法简单理解为'该对象有没有其他对象引用到它,即没有任何对象指向它,如果没有,该对象就会被垃圾回收机制回收
-
核心思想:设置引用数,判断当前引用数是否为0(对象是否不再需要)
-
引用计数器
-
引用关系改变时修改引用数字(++或--)
-
引用数字为0时立即回收
const user1 = { age: 11 } const user2 = { age: 22 } const user3 = { age: 33 } // 代码执行完 user1、user2、user3对象被nameList引用 所以不会被当作垃圾回收 const nameList = [user1.age, user2.age, user3.age] function fn() { const name = 1 const age = 2 } // 当函数调用完毕之后 name和age的引用数变为0 被当作垃圾处理 fn()
引用计数法优缺点
-
优点
- 发现垃圾时立即回收(根据对象当前引用是否为0判断是否为垃圾,如果发现为0时就立即释放空间)
- 最大限度减少程序暂停
-
缺点
-
无法回收循环引用的对象
function fn() { const obj1 = {} const obj2 = {} obj1.name = obj2 obj2.name = obj1 return 'xx' } fn()
-
时间开销大、资源消耗大
-
标记清除算法
为了解决循环引用的问题,现代浏览器都采用标记清除算法
该算法把“对象是否不再需要”简化定义为“对象是否可以可达”’
-
核心思想:分标记和清除两个阶段完成
-
遍历所有对象找标记活动对象
-
遍历所有对象清除没有标记对象
-
回收相应的空间
标记清除算法优缺点
- 优点:解决循环引用问题
- 缺点:
- 空间碎片化:回收的垃圾在地址上不连续的,如果后面申请的对象空间刚好匹配所回收的空间,就可以使用,如果没有满足的大小,就需要重新申请内存空间;空间不能得到最大化的使用,浪费空间
- 不会立即回收垃圾对象
标记整理算法
在标记清除时,清除数据后会导致清除的空间不再连续,下次存储数据时也是不连续的,所以在标记清除上增加了对内存空间的整理也就是(标记整理),解决了空间碎片化问题,其实就是标记清除的增强版
-
标记阶段的操作和标记清除一样
-
清除阶段先执行整理,移动对象位置
优点:减少碎片化,标记清除的提升,标记阶段一样,只是在清除阶段多了整理内存空间的步骤
缺点:不会立即回收垃圾对象
网友评论