文章目录
JVM垃圾回收机制
提示:以下是本篇文章正文内容,下面案例可供参考
一、⼀个对象从加载到JVM,再到被GC清除,都经历了什么过程?
- ⽤户创建⼀个对象,JVM⾸先需要到⽅法区去找对象的类型信息。然后再创建对象。
- JVM要实例化⼀个对象,⾸先要在堆当中先创建⼀个对象。-> 半初始化状态
- 对象⾸先会分配在堆内存中新⽣代的Eden。然后经过⼀次Minor GC,对象如果存活,就会进⼊S区。在后续的每次GC中,如果对象⼀直存活,就会在S区来回拷⻉,每移动⼀次,年龄加1。-> 多⼤年龄才会移⼊⽼年代? 年龄最⼤15, 超过⼀定年龄后,对象转⼊⽼年代。
- 当⽅法执⾏结束后,栈中的指针会先移除掉。
- 堆中的对象,经过Full GC,就会被标记为垃圾,然后被GC线程清理掉。
二、怎么确定⼀个对象到底是不是垃圾?
- 引⽤计数: 这种⽅式是给堆内存当中的每个对象记录⼀个引⽤个数。引⽤个数为0的就认为是垃圾。这是早期JDK中使⽤的⽅式。引⽤计数⽆法解决循环引⽤的问题。
- 根可达算法: 这种⽅式是在内存中,从引⽤根对象向下⼀直找引⽤,找不到的对象就是垃圾。
三、JVM有哪些垃圾回收算法?
- MarkSweep 标记清除算法:这个算法分为两个阶段,标记阶段:把垃圾内存标记出来,清除阶段:直接将垃圾内存回收。这种算法是⽐较简单的,但是有个很严重的问题,就是会产⽣⼤量的内存碎⽚。
- Copying 拷⻉算法:为了解决标记清除算法的内存碎⽚问题,就产⽣了拷⻉算法。拷⻉算法将内存分为⼤⼩相等的两半,每次只使⽤其中⼀半。垃圾回收时,将当前这⼀块的存活对象全部拷⻉到另⼀半,然后当前这⼀半内存就可以直接清除。这种算法没有内存碎⽚,但是他的问题就在于浪费空间。⽽且,他的效率跟存货对象的个数有关。
- MarkCompack 标记压缩算法:为了解决拷⻉算法的缺陷,就提出了标记压缩算法。这种算法在标记阶段跟标记清除算法是⼀样的,但是在完成标记之后,不是直接清理垃圾内存,⽽是将存活对象往⼀端移动,然后将端边界以外的所有内存直接清除。
四、什么是STW?
STW: Stop-The-World,是在垃圾回收算法执⾏过程当中,需要将JVM内存冻结的⼀种状态。在STW状态下,JAVA的所有线程都是停⽌执⾏的-GC线程除外,native⽅法可以执⾏,但是,不能与JVM交互。GC各种算法优化的重点,就是减少STW,同时这也是JVM调优的重点。
五、JVM有哪些垃圾回收器?
新⽣代收集器:
- Serial
- ParNew
- Parallel Scavenge
⽼年代收集器:
- CMS
- Serial Old
- Parallel Old
整堆收集器:
- G1
六、垃圾回收分为哪些阶段
GC分为四个阶段:
第⼀:初始标记 标记出GCRoot直接引⽤的对象。STW
第⼆:标记Region,通过RSet标记出上⼀个阶段标记的Region引⽤到的Old区Region。
第三:并发标记阶段:跟CMS的步骤是差不多的。只是遍历的范围不再是整个Old区,⽽只需要遍历第⼆步标记出来的Region。
第四:重新标记: 跟CMS中的重新标记过程是差不多的。
第五:垃圾清理:与CMS不同的是,G1可以采⽤拷⻉算法,直接将整个Region中的对象拷⻉到另⼀个Region。⽽这个阶段,G1只选择垃圾较多的Region来清理,并不是完全清理。