看看JVM是怎么打扫卫生的--垃圾回收机制

垃圾收集器

主要对堆空间进行垃圾回收,堆空间主要存放的是实例对象,首先我们要判断是否还存活?
1.引用计数法
给对象添加一个引用计数器,用一次就加1,引用失效就减1,等于0的时候说明这个对象就是废物咯,可以清理掉的垃圾。
可能引发的问题:两个对象互相引用,会导致这两个对象永远不会被回收。

2.可达性分析算法
选一个对象作为root起点,向下引用,不能到达的对象说明可以进行回收
引用分为四种:强引用,软引用,弱引用,虚引用。

下面进入正题,讲一讲垃圾回收算法都有哪些?

1.标记清除算法
分两个步骤,标记和清除。标记所有可以被垃圾回收的对象,然后清除掉所有被标记的对象。
产生的问题:效率问题,会产生很多碎片化的空间,导致利用率不高。

2.复制算法
把可用的内存一分为二,每次用完一半,就把存活的对象复制到另一半内存上去,然后把使用过的内存券不清理掉。
回收新生代用的就是这种算法,但是比例不是1:1,内存会被分成Eden区和两块Survivor区,比例是8:1:1,当垃圾回收的时候,会把Eden区的可用对象和Survivor可以对象复制到另一块Survivor区。

3.标记整理算法
把所有可用对象都一边移动,直接回收边界外的内存。

4.分代垃圾收集算法
根据对象的生命周期将java内存进行分代,分称老年代和新生代,根据不同年代的区域使用不同的收集算法。

下面讲一讲垃圾收集器

针对年轻代和老年代有不同的垃圾收集器,目前据我了解的有7种垃圾收集器。垃圾收集器之间可以搭配使用。

1.Serial收集器
这个垃圾收集器是针对年轻代的,它是单线程工作的。垃圾回收的时候会停掉其他线程,所有会产生一点停顿。这种垃圾收集器简单高效。

2.ParNew收集器
它就是Serial收集器的多线程版本,首选是年轻代收集器。

3.Parallel Scavenge收集器
新生代收集器,使用复制算法。

4.Serial Old
老年代单线程收集器,使用标记整理算法。

5.Parallel Old
老年代多线程收集器,使用标记-整理算法。

6.CMS收集器
是老年代收集器。最短回收停顿时间为目标的收集器。基于标记清除算法。并发收集低停顿。

初始标记
并发标记
重新标记
并发清除

缺点:会产生大量空间碎片

7.G1收集器
G1收集器是一个基于标记整理算法的收集器,它能非常精准的控制停顿。G1将java堆划分成多个大小相同的区域,根据每个区域的垃圾多少进行排序,优先回收垃圾最多的区域。

年轻代是怎么变成老年代的呢?
jvm中默认是15次垃圾回收没有被回收的对象会进入老年代。没触发一次年轻代垃圾回收,都会把Eden区和幸存者区的有用对象复制到to幸存者区,然后交换from幸存者区和to幸存者区。年满15周岁的年轻代对象升级为老年代。
当然了,也有搞特殊走后门的,如果进入年轻代的对象太大,年轻代已经放不下了,这时会触发年轻代垃圾回收,还是放不下直接进入老年代。如果幸存者区有很多年龄相同的对象,并切数量超多了一半,这时大于或者等于这个年龄的对象就会进入老年代。

原创文章 41 获赞 11 访问量 1474

猜你喜欢

转载自blog.csdn.net/weixin_44038332/article/details/104905955