架构师训练营 week9 作业
作业一:JVM垃圾回收总结
如何辨别一个对象是存是亡?
引用计数法
它的做法是为每个对象添加一个引用计数器,用来统计指向该对象的引用个数。一旦某个对象的引用计数器为 0,则说明该对象已经死亡,便可以被回收了。
具体实现:
如果一个引用被赋值为一个对象,那么这个对象的引用计数就+1;如果一个指向某一对象的引用被赋值为了其他值,那么将该对象的引用计数器 -1。
也就是说,我们需要截获所有的引用更新操作,并且相应地增减目标对象的引用计数器。
另一个引用计数方式的问题:无法处理循环引用。例如a和b之间相互引用,a 和 b 实际上已经死了,但由于它们的引用计数器皆不为 0,在引用计数法的心中,这两个对象还活着。
可达性分析算法
目前JVM主要是通过可达性分析算法来实现。
这个算法的实质在于将一系列 GC Roots 作为初始的存活对象合集(live set),然后从该合集出发,探索所有能够被该集合引用到的对象,并将其加入到该集合中,这个过程我们也称之为标记(mark)。最终,未被探索到的对象便是死亡的,是可以回收的。
三种方法清理
清理
将垃圾内存占用的对象清理掉。其实并不会对这些对象真正清理,而是记录一个空闲标志,并记录在一个空闲列表里。当再次需要时取出。
压缩
存活对象拷贝到头里。
复制
复制到另外的空间
使用中更多的使用压缩和复制
分代垃圾回收
思路:扫描空间少,回收速度块。
分成:
新生代 : Eden区 -> From区 -> To区
具体回收过程,就是采用复制的算法。
老年代
To区 -> 老年代
垃圾回收器
串行回收器:启动一个垃圾回收线程,所有线程停止运行,stop the world
并行回收器:启动多个垃圾回收线程(针对CPU核数),stop the world 时间短
并发回收器CMS:
把整个过程分的更详细,初始标记,并发标记,重标记,清理标记四个阶段。垃圾回收线程和用户线程并发执行。
G1回收器:
主流,使用更多。把内存使用空间划分为更小的区域,空间越小速度越快。针对这些小块进行垃圾回收。对用户程序影响小。没有之前的并发复杂性。
通过最大GC暂停时间来控制。动态调整回收策略。
week9 总结
评论