版本:JDK8
一、阅读前热身:
1、了解jvm启动流程:
2、了解硬件、系统、进程三个层面的内存之间的概要内存分配,一张图你就懂:
3、下面是需要背住的重点,敲黑板!!堆内存分配,想了解参数的可以到最下面看下备注和建议:
先来个日志(看不懂那就看图):
备注:
Heap(堆内存)=eden+2survivor(年轻代)+ParOldGen(老生代)+Perm(jdk8以前)。
jdk8以后将永久代替换为MetaSpace(元空间)存在于本地内存。
from survivor 和 to survivor大小相同,且保证一个为empty.
二、实战演练
1、JVM GC执行日志:
gc解析日志:我们可以看到 由于年轻代的eden区100%,触发了红色框说由于内存分配失败,所以gc回收,eden区gc后剩余60567k(看年轻代蓝色变化)存放于年轻代的survivor(看绿色survivor增长69%)。
红色框解读:
[PSYoungGen: 524800K->60567K(611840K)] 。格式为[PSYoungGen: a->b(c)].
PSYoungGen,表示新生代使用的是多线程垃圾收集器Parallel Scavenge。a为GC前新生代已占用空间,b为GC后新生代已占用空间。新生代又细分为一个Eden区和两个Survivor区,Minor GC之后Eden区为空,b就是Survivor中已被占用的空间。括号里的c表示整个年轻代的大小。
524800K->60647K(2010112K),格式为x->y(z)。x表示GC前堆的已占用空间,y表示GC后堆已占用空间,z表示堆的总大小。
由新生代和Java堆占用大小可以算出年老代占用空间,此例中就是2010112K-611840K=1398272k。
[Times: user=0.46 sys=0.02, real=0.13 secs] 提供cpu使用及时间消耗,user是用户态消耗的cpu时间,sys是系统态消耗的cpu时间,real是实际的消耗时间。
2、JVM gc执行过程:
执行过程如上图根据执行日志顺序,
第一步新生代内存分配区域eden空间100%后,无法分配内存。
第二步gc回收、保留一部分剩余对象存放sur