GC机制

工作目的

找到堆中无用的对象,并将这些对象所占用的空间回收,重新使用

算法思路

对象组成集合,或者树状结构,从根部开始找

能找到的都是存活对象,找不到的就是应该被回收的

判断存活

可用计数:每个对象有一个引用计数,新增引用加1,释放减1,计数为0时可回收。无法解决对象相互引用的问题

可达性分析:从GC Roots开始搜索,所走过的路径叫引用链。当一个对象到GC Roots直接没有引用链时,即对象无引用,不可达,可回收

新域会被分为3个部分:第一个部分叫Eden。(伊甸园??可能是因为亚当和夏娃是人类最早的活动对象?),另两个部分称为辅助生存空间(幼儿园),我这里一个称为A空间(From sqace),一个称为B空间(To Space)。

堆中新域的copying算法

对于新生成的对象,都放在Eden中;当Eden充满时(小孩太多了),GC将开始工作,首先停止应用程序的运行,开始收集垃圾;

把所有可找到的对象都复制到A空间中,一旦当A空间充满,GC就把在A空间中可找到的对象 都复制到B空间中(会覆盖原有的存储对象),当B空间满的时间,GC就把在B空间中可找到的对象都复制到A空间中,AB在这个过程中互换角色;

在活动对象经过一定次数的GC操作后,这些活动对象就会被放到旧域中,对于这些活动对象,新域的幼儿园生活结束了。

新域为什么要这么折腾?应用程序生成的绝大部分对象都是短命的,copying算法最理想的状态是,所有移出Eden的对象都会被收集,因为这些都是短命鬼,经过一定次数的GC后应该被收集。那么移入到旧域的对象都是长命的,这样可以防止AB空间的来回复制影响应用程序。

实际上这种理想状态是很难达到的,应用程序中不可避免地存在长命的对象,copying算法的发明者要这些对象都尽量放在新域 中,以保证小范围的复制,压缩旧域的开销可比新域中的复制大得多。

旧域的tracing算法

称为标记-清除-压缩收集器,注意,这有一个压缩,这是个开销挺大的操作。

算法详细可以:https://www.cnblogs.com/ityouknow/p/5614961.html

young generation比例越大,不一定最好。

将young的大小设置为大于总堆大小的一半时会造成效率低下。如果设置得过小,又会因为young generation收集程序不得不频繁运行而造成瓶颈。

总结
1.JVM堆的大小决定了GC的运行时间。如果JVM堆的大小超过一定的限度,那么GC的运行时间会很长。
2.对象生存的时间越长,GC需要的回收时间也越长,影响了回收速度。
3.大多数对象都是短命的,所以,如果能让这些对象的生存期在GC的一次运行周期内,wonderful!
4.建立与释放 对象的速度决定了垃圾收集的频率。
5.如果GC一次运行周期超过3-5秒,这会很影响应用程序的运行,如果可以,应该减少JVM堆的大小了。
6.前辈经验之谈:通常情况下,JVM堆的大小应为物理内存的80%。

参考:https://blog.csdn.net/jiafu1115/article/details/7024323

猜你喜欢

转载自www.cnblogs.com/jhin-wxy/p/9016879.html