目录
1、如何判定对象为垃圾对象
1.1、引用技术法
1.2、可达性分析法
2、如何回收垃圾对象
2.1、回收对象的几种算法
2.1.1、标记-清除算法
2.1.2、复制算法
2.1.3、标记-整理算法
2.1.4、分代收集算法
2.2 、主流垃圾回收器简介
2.2.1、Serial
2.2.2、Parnew
2.2.3、Cms
2.2.4、G1
各个知识点讲解
1.1、引用计数法
思路:在对象中添加一个计数器,每有一个地方引用到该对象,则计数器+1,引用失效,则计数器-1。当计数器为0的时候该引用失效,则可以该对象进行回收。但该方法简单粗暴,效率也不错,但很少被虚拟机用到,这是为啥??就是因为它无法解决对象间相互引用的问题。
网上找的例子如下:

该代码在内存中的简易示例图:

代码运行到第7行的时候,两个对象的引用计数都为2,那么当运行到9行结束的时候,两个对象的引用计数都为1,因为两个对象间存在相互引用,所以无法把两个对象的技术清零。这两个对象也就无法被回收掉。
1.2、可达性分析
因为引用计数法的缺陷,由此又推出了“可达性分析法”。思路:通过一些列称之为GC Roots的对象作为根节点,往下寻找,搜索过的路径称为引用链,没有在引用链上的对象则为垃圾对象。如图:

那么GC Roots的对象是如何来的呢??网上也列举了几类来源:
1、虚拟机栈的引用对象。比如:在方法methodA中的ObjectA对象
public void methodA() {
ObjectA a = new ObjectA();
}
2、方法区中静态属性引用的对象。比如:ClassB属于ClassA中的静态属性,此时ClassB()就属于静态属性引用的对象 。
public Class A {
public static ClassB classB = new ClassB();
}
3、方法区中常量的引用对象。比如:protect final String url = "hello word";
4、本地方法栈JNI引用的对象(同第一点虚拟机栈)
2.1.1、标记-清除算法
如何找到垃圾对象的方法说完了,接下来说说怎么把垃圾对象回收。
第一种最low的就是标记-清除算法。它原理就是运用可达性分析法找到虚拟机栈中的垃圾对象做标记,然后把标记的垃圾对象做清除。这种方法的弊端有两个,一个是执行效率低(因为内存碎片太多,内存不连续,导致分配大空间内存的时候找不到合适的空间进行分配,这时候还需要进行另一次的垃圾回收十分影响性能),一个是会产生太多的内存碎片,因为标记的垃圾对象在内存中不是连续的,所以有该问题。如图:
清除前:

清除后:

这样子会产生越来越多的不连续的空间。
2.1.2、复制算法
复制算法是用来解决标记-清除算法的两个弊端:一是效率问题 而是内存碎片化问题。它的思路是:把堆内存分为两块用的时候只用一块,我们创建对象只在一块创建,然后进行回收,回收后把没有回收掉的内存空间放到另一个内存块并连续的排列,这样就不会有碎片化问题,又因为少了内存碎片整理加上copy的速度也是超级快,所以速度相对于标记清除算法来说快很多。但这样做的弊端就是会浪费一半的空间。如图:
回收前:

回收后:

但实际上虚拟机载不可能浪费百分之50的空间来做这个事情。复制算法一般是在新生代(关于新生代老年代不在这里过多描述)中使用。新生代分为Eden与Survivor两块区域 Survivor有两块命名为from与to。空间大小为:8:1:1。
我们会把Eden与其中一块Survivor中的垃圾对象清除,然后把存活对象放到另一块Survivor中,这样子损失的空间大概是新生代的百分之十也就是一块Survivor空间的大小。
2.1.3、标记-整理算法
刚才也提到了复制算法一般用于新生代因为新生代的对象存活率低一般在百分之十左右。但是对于老年代呢老年代的存活率高达百分之九十,这时候用复制算法显然是不合适的(把存活的百分之九十的对象放到百分之十空间的Svuvivor空间里,这时候还需要进行内存的分配担保)。这时候标记-整理算法孕育而出。
标记-整理算法与标记-清除算法相同之处在于前面标记的阶段是相同的。不同的是标记-整理算法在后阶段是整理后再进行清除。具体的做法内存中设定了隐形一个分界线,把需要回收的内存放一边,不需要回收的内存放另一边,然后再把需要回收的内存统一清除掉。这样做的效率会比标记-清除的算法效率要高。
需要回收的往分界线的右边,存活的往左边走,然后再把需要回收的内存回收掉。
回收前:

回收后:

2.1.4、分代收集算法
分代收集算法实际上是标记-整理算法与复制算法的结合。就是在新生代区域用复制算法在老年代用标记-整理算法。
未完待续。。。。。。
参考文献:
https://blog.youkuaiyun.com/g_66_hero/article/category/8296240
本文深入解析了垃圾回收机制,包括对象判定为垃圾的两种方法:引用计数法和可达性分析法;以及四种垃圾回收算法:标记-清除、复制、标记-整理和分代收集算法。同时介绍了几种主流的垃圾回收器。
1847

被折叠的 条评论
为什么被折叠?



