1)一个java进程对应这个一个JVM实例,Runtime,就对应着一个运行时数据区,一个进程中的多个线程,共享同一份堆空间和方法区,而栈和程序计数器使每一个线程私有的
2)通过-Xms10m -Xmx10m是初始堆空间和最大堆空间
3)堆空间在物理上可以不连续,逻辑上是连续的,而栈只存在入栈和出栈,不会有垃圾回收
4)堆上面有着各个线程的缓冲区,每一个线程都有着自己的小空间,这个小空间就是TLB,这个时候并发性会更好;
5)不是没有引用执行对象,对象就立即回收,只有说堆中快满了不足了,才会执行GC垃圾回收,不是栈中的引用弹出栈,对象就立即被回收了,否则GC的频率过高,就会影响用户线程的执行,如果一直进行垃圾回收,就会影响用户线程的执行,所以应该将堆空间的区域设置的大一些合理的分配,减少GC,让用户线程执行时间长一些,提升吞吐量,频繁的GC会影响性能,都是Throwable的子类,error不可控,exception一般需要手动去捕获,比如说javaheapspace
6)-Xms10m -Xmx10m -XX:+PrintGCDetails
查看堆占用的情况:
伊甸园区:幸存者1区:幸存者2区=8:1:1
默认新生代和老年代的占比是2:1
新生代:伊甸园区+幸存者1区+幸存者2区
yonggc/minor GC:触发条件时伊甸园区满了幸存者区满了不会触发yonggc,但是yongGC回收的过程中会顺便带上回收幸存者区,伊甸园区满了之后再来对象,这个时候再次进行垃圾回收,会产生STW,需要进行判断各个对象是否是垃圾,不是垃圾的移动到幸存者1区或者是幸存者2区,放在空的区,空的幸存者区是to(从伊甸园区的对象首先放到幸存者1区),不空的是from;
1)如果幸存者0区或者是幸存者1区放不下伊甸区的对象,直接将对象放到老年代
如果说伊甸园区和幸存区的比例比较大的话,幸存者1区和幸存者2区所占的空间比较小,理想情况下所有的伊甸区中的垃圾对象都被回收了,很少的对象存活到幸村区,但是一般情况下,幸村区的对象比较少,如果再向伊甸园区放对象,很容易导致伊甸园区对象放在幸存区,幸村区容易存不下,于是直接给放到old区,会导致minorGC失去意义,因为正常进行yongGC的时候幸存者1区和幸存者2区也会进行垃圾回收,而现在有些对象没有达到阈值15就直接到达老年代了,minorGC意义不大况且尽量说先把对象在新生代回收,分代意义更小
2)如果伊甸园区比较小,yonggc会频繁触发,会影响用户进程,影响STW的时间
MarkWord里面存放对象的GC年龄只有4位,所以最大也只是15
图解对象分配的过程 - 掘金 (juejin.cn)
JVM调优:GC回收能够少一些,GC扫描的过程中会出现STW,用户线程终止
从频率上看大部分情况下都是回收的是新生代,伊甸园区满的时候才会触发youngGC,只有触发yongGC,才会顺便回收幸存者1区或者是幸存者2区
比如说有一个房间很多垃圾,GC标记过程中用户要STW
分代垃圾回收机制——老年代收集 - 掘金 (juejin.cn)
分代垃圾回收机制——老年代收集 - 掘金 (juejin.cn)
1)system.gc:
2)老年代空间不足:
TLAB
进行minorGC的时候要将新生代的对象往老年代里面进行存放,先看看老年代的最大可用连续空间是否大于新生代所有对象的总空间,如果比他大那么,说明这里面最坏的情况就是新生代的对象没有一个是垃圾,老年代肯定都是可以放得下
如果小于,说明此时minorGC不安全,那么继续判断这个参数,如果这个参数是true,那么会进行继续检查老年代最大可用连续空间是否大于历次劲升到老年代的对象的平均大小
这个参数永远是true
老年代GC垃圾回收慢