jvm垃圾回收

如何判断是否是垃圾?

1.引用计数法:对象被引用,计数器+1,对象取消引用,计数器-1,计数器为0,就可以回收,但是这种方式解决不了循环引用的问题,A引用B,B引用A,AB没有被其他对象引用,所以AB都是垃圾,但是计数器不为0。Java中也没有使用这种方式

2.可达性分析:A->B->C->D->B,有向关系构成一个有向图,可达性分析就是从根对象出发,遍历这个有向图,能够遍历到的就是存活对象,遍历不到的就是垃圾。根对象就是gcroot,做可达性分析的起点,这个就是java用来判断对象是否是垃圾的一个方式。可达性分析的过程?如何遍历标记判断的呢?这就使用到了三色标记法,三色标记法涉及到了遍历过程中对象的一个状态,白色表示没有被标记的对象,遍历完之后没有访问到,说明是不可达的对象,就是垃圾,灰色表示已经访问到,但是这个对象内部引用的其他对象,还没有被全部扫描到,黑色表示这个对象内部引用的其他对象,被全部扫描到,也就是确定存活的对象,这就是三色标记法。但是三色标记法也有缺点,其一是浮动垃圾,在并发标记的场景下,并发标记指的是做可达性分析过程和用户代码同时执行,可能出现刚把一个对象标记为黑色,但是用户代理一执行,这个对象就变成垃圾了,不再被引用,这就是浮动垃圾,但是这种情况影响不大,下一次GC的时候清理掉即可。其二是漏标问题,同样是标记的一个场景,把一个对象标记成白色(垃圾),但是一个黑色的对象突然引用了这个白色的对象,由于黑色对象是已经遍历完且已存活的对象,不会再遍历了,这是突然引用一个白色,导致这个白色是需要的,不是垃圾,由于这种标记的结果,但是他又要被GC回收,这种漏标的结果很严重,导致系统出问题,所以后面的垃圾回收器会使用一些方式专门去进行处理。

垃圾回收算法

标记清除,标记整理,复制算法。标记清除是从gcroot出发,遍历标记所有可达的对象,然后遍历堆清除所有不可达的对象,先标记后清除,清除完之后,这个内存区域空下来,就可以分配其他新的对象了。如何知道哪一块是空闲的,哪一块是可分配的,需要一个空闲列表去记录。标记清除缺点会产生内存碎片,回收10kb空间,下次来了7kb空间,此时3kb就是内存碎片。标记整理算法,先标记,然后把存活的对象移到内存的一边,另一边直接清理掉,但是移动对象的成本很高,停顿较大。第三种是复制算法,复制算法是将内存分成两个区域,分配对象的时候分配到一个区域,回收的时候,把存活对象复制到另外一块区域,然后把原来的区域清空,复制算法也没有内存碎片,但是空间利用率低,因为有一半空间是不使用的。复制算法适用于存活对象少,垃圾多的场景,因为复制的对象少了,标记清除和标记整理适用于垃圾少,存活对象多的场景,因为需要清理的少。

基于这种场景和垃圾回收算法的特点,jvm把堆区划分为新生代和老年代,新生代存放新出生的对象,生命周期长的就会放到老年代。新生代由于垃圾对象多,存活对象少,适合复制算法,老年代由存活时间长适用于标记清除和标记整理算法,针对不同的区域使用不同的垃圾回收算法,叫做分代回收算法,这也是java使用的垃圾回收算法。具体流程:堆分为新生代,老年代。新生代分为ENED,survivor0,suvivor1.一般来说,对象在eden区出生,当eden区不足时,触发一次young gc,把eden区和from 区存活的对象复制到to 区,存活对象寿命+1,然后清除eden区的垃圾,from 和 to交换,from 保存了存活的一个对象,这个时候young gc重复的过程,当to 区被填满,将里面的对象移动到老年代里,存活对象寿命到达阈值的时候,也会把对象从新生代移到老年代,这个阈值是15,因为这个对象经过15次gc还没有被回收,说明他比较重要,生命周期比较长,所以被放到GC不频繁的老年代里。当晋升到老年代对象过多,尝试触发young gc区清理新生代,减少晋升的量,当老年代数量还是够,触发full gc,会把新生代和老年代都清理一遍

相关推荐
期待のcode26 分钟前
Java虚拟机的非堆内存
java·开发语言·jvm
jmxwzy4 小时前
JVM(java虚拟机)
jvm
Maỿbe5 小时前
JVM中的类加载&&Minor GC与Full GC
jvm
人道领域6 小时前
【零基础学java】(等待唤醒机制,线程池补充)
java·开发语言·jvm
小突突突6 小时前
浅谈JVM
jvm
饺子大魔王的男人7 小时前
远程调试总碰壁?局域网成 “绊脚石”?Remote JVM Debug与cpolar的合作让效率飙升
网络·jvm
天“码”行空17 小时前
java面向对象的三大特性之一多态
java·开发语言·jvm
独自破碎E1 天前
JVM的内存区域是怎么划分的?
jvm
期待のcode1 天前
认识Java虚拟机
java·开发语言·jvm
leaves falling1 天前
一篇文章深入理解指针
jvm