JVM中GC

1、GC触发的条件

触发的条件有两种:(1)程序调用System.gc()时可以触发;(2)系统自身来决定GC触发的时机。

2、jvm内存分配

(1)对象分配:

    优先在Eden区分配:在大多数情况下,对象在新生代Eden区中分配,当Eden区中没有足够空间的分配时,系统调用一次Minor GC,将Eden中存活的对象和其中一块survivor中存活的对象移动到另一块的survivor区域,如果在Minor GC期间发现新生代存活对象无法放入空闲的survivor区,则会通过空间分配担保机制使对象提前进入老年代。

    大对象直接进入老年代:某些收集器提供了-XX:PretenureSizeThreshold的参数,大于该值的大对象直接在老年代分配,避免在Eden区和Survivor区之间产生大量的内存复制(例:需要大量连续内存的JAVA对象),因此大对象导致还有不少空闲内存就提前触发GC以获取足够的连续空间。

(2)对象晋升:

    年龄阈值:VM为每个对象定义了对象年龄(Age)计数器,对象在Eden出生并经过第一次Minor GC之后仍存活,且被Survivor区中每经过一次Minor GC后Age就+1,当增加到一定程度(MaxTenuringThreshold),将会晋升老年代。

    提前晋升:若在Survivor空间中相同年龄所有对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代。

3、jvm对象生死判定(何时回收)

    在java语言,都是通过可达性分析算法(并没有采用引用计数法,引用计数法无法解决循环引用的问题)进行对象存活与否的判定:通过称之为GC Root是的对象作为起点,然后向下搜索,搜索走过的路径称之为引用链,当一个对象到GC Roots没有任何引用链相连时,即说明该对象不可达。

 在java中,可作为GC Roots的对象包括:

(1)方法区:类静态属性引用的对象;

(2)方法区:常量引用的对象;

(3)虚拟机栈(本地变量表)中引用的对象;

(4)本地方法栈JNI(Native方法)中引用的对象;

4、VM常用参数整理

猜你喜欢

转载自blog.csdn.net/cold1sober/article/details/79985503