认识内存管理
-
不管什么样的编程语言,在代码的执行过程中都是需要给它
分配内存的。不同的是有些编程语言需要程序员手动管理内存,某些编程语言会可以自动帮管理内存 -
不管以什么样的方式来管理内存,内存的管理都会有如下的生命周期:
- 第一步:分配申请你需要的内存
- 第二步:使用分配的内存
- 第三步:不需要使用时,对齐释放
-
不同的编程语言对于第一步和第三步会有不同的实现
- 手动管理内存。如C、C++,包括早期的OC,都需要手动管理内存的申请和释放(free函数)
- 自动管理内存。如Java、JavaScript
JS内存分配方式
JS会在定义数据时为我们分配内存,不同的数据类型,内存的分配方式不同
- 对于
原始数据类型内存的分配还在执行时,直接在栈空间进行分配- 栈空间分配内存特点:有
固定的内存大小
- 栈空间分配内存特点:有
- 对于
复杂的数据类型内存的分配会在堆内存中开辟一个空间,并且将这块空间的地址值给到栈内存中变量引用- 堆内存分配内存特点:
没有固定的内存大小,通过内存地址访问
- 堆内存分配内存特点:
垃圾回收机制(GC)
因为内存的大小是有限的,所以当内存不再需要的时候,我们需要对其进行释放,以便腾出更多的内存空间。
在手动管理内存的语言中,需要我们自己手动的去释放不再需要的内存,但是这种方式效率很低,并且一不小心会产生内存泄漏,所以,现在大部分的变成语言都有自己的垃圾回收机制。
常见的GC算法
引用计数
- 引用计数:
- 当一个对象有一个引用指向它时,那么这个对象的引用就+1
- 当一个对象的引用为0时,这个对象就可以被销毁
- 引用计数的弊端——产生循环使用
此时,由于obj1和obj2的应用计数不是0,系统不会释放该内存空间,而obj1/obj2已经失去了引用,无法再被使用,故obj1,obj2将永远无法被系统回收
标记清除
- 标记清除
- 标记清除的核心思路是
可达性 - 这个算法是设置一个
跟对象,垃圾回收器会定期从这个根开始,找所有从跟开始有引用到的对象,对于那些没有被引用到的对象,就认为是不可用的对象 - 这个算法可以很好的解决循环引用的问题
- 标记清除的核心思路是