什么是GC?
GC是垃圾回收机制(Garbage Collection),是自动内存管理机制。GC主要负责堆上面的内存。
发展史:
手动垃圾回收:
一些编程语言(C、C++)需要程序员自己释放不需要的,分配在堆上的数据;如果释放的早了,后续对该数据访问就会出错,因为该数据可能已经被清空或者被分配或者还给了操作系统。这就是悬挂指针或者野指针(上面文章里面后面的例子中也有提到)
自动垃圾回收:
(PHP、Java、Go)由内存分配器和垃圾回收器(GC)担任分配和回收的工作,自动识别不再需要的数据并释放所占用的内存,主要的是去关注业务而不是去管理垃圾回收。不同语言的回收算法都不同
主流的GC算法:
1.引入计数: PHP、Python
为每一个对象维护一个计数器,当调用该对象的对象销毁时,计数 “-1” ,当计数器为 0 的时候收回该对象。
如果三个对象相互引用就会导致每个对象计数都是1,即使这三个都没有被使用了,但是GC依然会认定为在被使用(计数>0)。而且在有多线程下,都调用一个对象,这样可能会导致计数器只加了一次,所以又会加锁或者其他方法增加了GC压力
优点: 对象回收快,不会出现内存耗尽或者达到某个阈值的时候再回收
缺点: 对循环引用的处理不太好,实时维护这么多计数器也是有损耗
2.分代收集: Java
按照对象的生命周期长短将内存划分为 “新生代” 和 “老年代”,生命周期短的放入 新生代,反之放入 老年代,不同代有不同的回收算法和回收频率
优点: 回收性能好
缺点: 算法复杂
3.三色标记法:Go
因为人们发现一个对象需要被回收,并不是因为没有对象调用了,而是从一个根(root)出发,该对象无法在内存中找到了(JVM的可达性分析算法)。从一系列的被称为 GC roots 的根作为起始点开始向下搜索(深度优先BFS 或 广度优先DFS)
常见的GC roots有 常量、静态引用、栈上的引用、本地方法栈引用等,年轻代的gcroots还要多一些,包括常量池之类的
起初是双色标记法,但是有缺陷,后来就舍弃了。
后面的内容移步到下面链接里我写的笔记,重新写在CSDN编辑太麻烦了