JS内存管理和垃圾回收机制

98 阅读2分钟

认识内存管理

  • 不管什么样的编程语言,在代码的执行过程中都是需要给它分配内存的。不同的是有些编程语言需要程序员手动管理内存,某些编程语言会可以自动帮管理内存

  • 不管以什么样的方式来管理内存,内存的管理都会有如下的生命周期:

    • 第一步:分配申请你需要的内存
    • 第二步:使用分配的内存
    • 第三步:不需要使用时,对齐释放
  • 不同的编程语言对于第一步和第三步会有不同的实现

    • 手动管理内存。如C、C++,包括早期的OC,都需要手动管理内存的申请和释放(free函数)
    • 自动管理内存。如Java、JavaScript

JS内存分配方式

JS会在定义数据时为我们分配内存,不同的数据类型,内存的分配方式不同

  • 对于原始数据类型内存的分配还在执行时,直接在栈空间进行分配
    • 栈空间分配内存特点:有固定的内存大小
  • 对于复杂的数据类型内存的分配会在堆内存中开辟一个空间,并且将这块空间的地址值给到栈内存中变量引用
    • 堆内存分配内存特点:没有固定的内存大小,通过内存地址访问

image.png

垃圾回收机制(GC)

因为内存的大小是有限的,所以当内存不再需要的时候,我们需要对其进行释放,以便腾出更多的内存空间。

在手动管理内存的语言中,需要我们自己手动的去释放不再需要的内存,但是这种方式效率很低,并且一不小心会产生内存泄漏,所以,现在大部分的变成语言都有自己的垃圾回收机制。

常见的GC算法

引用计数

  • 引用计数:
    • 当一个对象有一个引用指向它时,那么这个对象的引用就+1
    • 当一个对象的引用为0时,这个对象就可以被销毁 image.png
  • 引用计数的弊端——产生循环使用

image.png

image.png

此时,由于obj1和obj2的应用计数不是0,系统不会释放该内存空间,而obj1/obj2已经失去了引用,无法再被使用,故obj1,obj2将永远无法被系统回收

标记清除

  • 标记清除
    • 标记清除的核心思路是可达性
    • 这个算法是设置一个跟对象,垃圾回收器会定期从这个根开始,找所有从跟开始有引用到的对象,对于那些没有被引用到的对象,就认为是不可用的对象
    • 这个算法可以很好的解决循环引用的问题

image.png