Java教程:JVM相关问题整理(八)

开课吧开课吧锤锤2021-03-10 15:34

    Java编程语言是一种简单、面向对象、分布式、解释型、健壮安全、与系统无关、可移植、高性能、多线程和动态的语言。如今Java已经广泛应用于各个领域的编程开发。

Java

    4.MinorGC和FullGC触发条件

    MinorGC触发条件:

    当Eden区满时,触发MinorGC。

    FullGC触发条件:

    System.gc()方法的调用

    老年代空间不足

    方法区空间不足

    通过MinorGC后进入老年代的平均大小大于老年代的可用内存

    由Eden区、FromSpace区向ToSpace区复制时,对象大小大于ToSpace可用内存,则把该对象转存到老年代,且老年代的可用内存小于该对象大小

    补充问题:

    MinorGC和FullGC有什么不一样吗?

    新生代GC(MinorGC):指发生在新生代的垃圾收集动作,因为Java对象大多都具备朝生夕灭的特性,所以MinorGC非常频繁,一般回收速度也比较快。

    老年代GC(MajorGC/FullGC):指发生在老年代的GC,出现了MajorGC,经常会伴随至少一次的MinorGC(但非绝对的,在ParallelScavenge收集器的收集策略里就有直接进行MajorGC的策略选择过程)。MajorGC的速度一般会比MinorGC慢10倍以上。

    5.GC中Stoptheworld(STW)

    垃圾回收首先是要经过标记的,对象被标记后就会根据不同的区域采用不同的收集方法。垃圾回收并不会阻塞我们程序的线程,他是与当前程序并发执行的。所以问题就出在这里,当GC线程标记好了一个对象的时候,此时我们程序的线程又将该对象重新加入了“关系网”中,当执行二次标记的时候,该对象也没有重写finalize()方法,因此回收的时候就会回收这个不该回收的对象。 虚拟机的解决方法就是在一些特定指令位置设置一些“安全点”,当程序运行到这些“安全点”的时候就会暂停所有当前运行的线程(StopTheWorld所以叫STW),暂停后再找到“GCRoots”进行关系的组建,进而执行标记和清除。

    这些特定的指令(安全点)位置主要在:

    循环的末尾

    方法临返回前/调用方法的call指令后

    可能抛异常的位置

    停顿类型就是STW,至于有GC和FullGC之分,主要是FullGC时STW的时间相对GC来说时间很长,因为FullGC针对整个堆以及永久代的,因此整个GC的范围大大增加;还有就是他的回收算法就是“标记–清除–整理”,这里也会损耗一定的时间。所以我们在优化JVM的时候,减少FullGC的次数也是经常用到的办法。

    以上内容由开课吧老师张彦峰ZYF提供,更多Java教程尽在开课吧广场Java教程频道。

有用
分享