一、堆内存逻辑分区
这里图片写错了: 新生代比老年代应该是 1:2
对象来了,先会在stack上进行分配,stack放不下才到了Eden区,Eden区经过一次回收到了幸存者1区。进入old区的年龄可以通过参数配置,一般是15
二、MinorGC和MajorGC
三、逃逸
如果一个对象没有被引用指向它,被限定在一个范围里,则叫做没逃逸
new User被限定在alloc方法中,没有对象指向它
四、对象何时进入老年代
不同垃圾回收器不一样,可以通过用参数指定,PS垃圾回收器6次就进入了
年龄15并不是定死的规则,有的垃圾回收算法会采用动态的计算方法来判定对象进入老年代的年龄,大致逻辑如下:年龄从小到大进行累加,当加入某个年龄段后,累加和超过幸存者区域50%的时候,就从这个年龄段的往上的年龄对象进行晋升。50%这个百分比可以通过参数: TargetSurvivorRatio进行设置
五、怎么看JVM参数?
命令行直接输入
java -XX:+PrintFlagsFinal -version
就可以查看所有参数
想搜索自己想要的就加搜索关键字:
java -XX:+PrintFlagsFinal -version | grep Tenure
六、垃圾回收器
JDK8默认的垃圾回收器是: PS+PO ,Parallel Scavenge + Parallel Old
JDK9默认的是G1
目前所有的垃圾回收器都有 STW,即垃圾回收的时候要停止工作线程
Serial
STW(stop the world)
这种收集器是一个单线程的收集器,即垃圾收集时只有一个垃圾收集线程在工作,但是它的“单线程”不仅仅说明它只会使用一个CPU或者一条收集线程去完成垃圾收集工作,更重要的是在于它在进行垃圾收集时,必须暂停其他所有的工作线程,直到它收集结束(Stop-the-World)。
-XX:+UseSerialGC参数可以指定年轻代和老年代都是用串行收集器,即年轻代用Serial GC,老年代用Serial Old GC。
CMS(concurrent mark sweep)
CMS收集器是基于“标记–清除”(Mark-Sweep)算法实现的。
整个过程分为四个步骤:
1.初始标记 (Stop the World事件 CPU停顿, 很短) 初始标记仅标记一下GC Roots能直接关联到的对象,速度很快;
2.并发标记 (收集垃圾跟用户线程一起执行) 初始标记和重新标记任然需要“stop the world”,并发标记过程就是进行GC Roots Tracing的过程;并发标记时间占了整个周期80%的时间左右,注意是并发而不是并行
3.重新标记 (Stop the World事件 CPU停顿,比初始标记稍微长,远比并发标记短)修正并发标记期间因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录,这个阶段的停顿时间一般会比初始标记阶段稍长一些,但远比并发标记时间短
4.并发清理 -清除算法;
如果内存几十个G,用PS怎么调优都没有用,因为调优是有上限的,这时候就得用CMS了