1. 堆的构造
2. 堆的 GC 过程
3. 堆调优参数简介
之前在 深刻了解 JVM(一)——JVM 简介和运行时数据区构造 一篇文章中,咱们简略地介绍过,堆的内存构造:分为新生区,养老区,和永恒区(jdk1.8 曾经将养老区更新为元空间),明天咱们来认真解说一下堆的内存散布,堆的 GC 过程以及简略的堆调整参数。
1. 堆的构造
首先,整个堆分为新生代和老年代,新生代占 1 / 3 的堆空间 (新生代中, 伊甸园和辛存者 0 区和 1 区又是 8:1:1 的比例 ), 老年代占 2 / 3 的堆空间,元空间(永恒代)不在JVM 的内存里,在操作系统内存中,如图所示。
永恒区:它在一个常驻内存区域,用于寄存 JDK 本身所携带的元数据,被装载进此区域的数据是不会被回收掉的,敞开 JVM 才会开释该区域。
2. 堆的 GC 过程
GC(Garbage Collection), 是在 JAVA 堆内存区域满了之后,产生的一种垃圾收集行为。当咱们一直地 new 对象的时候,内存的可用区域必定一直地缩小。
每次 new 的对象,不出意外都会在新生代的伊甸园(Eden)区域调配。
eden 区域满之后,会产生什么?
当 Eden 区域满的时候 ,咱们就会触发一次 youngGc, 这时, 把还活着的对象拷贝到 Survivor0 区
当 Eden 区再次触发 GC 的时候会扫描 Eden 区和 From 区域 ,对这两个区域进行垃圾回收, 通过这次回收后还存活的对象,则间接复制到 Survivor1 区域,同时,把这些对象的年龄 +1。
始终循环上述步骤,局部对象会在 Survivor0 区和 1 区复制来复制去,如此替换 15 次,最终如果还是存活,就存入到老年代。
当新生代所有区域内存都不够的时候,就会进行新生代和老年代的两个区域的 GC,如果新生代和老年代两个区域的 GC 产生之后,内存还是不够,就会产生 FullGC,就是所有区域的 GC,如果内存还是不够,就会产生 OOM。
3. 堆调优参数简介
在介绍堆调优参数之前,咱们先来介绍两个 JAVA 办法:
// 虚拟机最大应用的内存值,默认为物理内存的 1 /4
System.out.println(Runtime.getRuntime().maxMemory()/1024/1024+"MB");
// 虚拟机初始应用物理内存大小,默认物理内存的 1 /64
System.out.println(Runtime.getRuntime().totalMemory()/1024/1024+"MB");
用这两个办法,能够打印并且失去以后运行该办法的虚拟机的堆值,咱们来打印一下试试:
我的电脑内存是 16GB,两个理论值正是大概在 1 / 4 和 1 /64 的区间左右。
接下来咱们能够用两个参数来调整 java 虚拟机堆的大小
-Xms1024m 将堆内存的初始值设置为 1024m
-Xmx1024m 将堆内存的最大值设置为 1024m
咱们在 idea 的我的项目启动处,抉择编辑参数
把 -Xms1024m -Xmx1024m 输出到 VM Option 外面
再执行刚刚那两个办法:
JVM 堆大小调整胜利!
接下来咱们模仿一下 OOM,这时要设置一个参数 -XX:+PrintGCDetails
在控制台打印垃圾收集信息
String oom = "666";
while (true) {oom += oom + "66666666666666666666666666666666666666666666666666666";}
咱们只有一直地 new 对象,内存总有塞不下的一天,同时,咱们还能够察看 GC 的信息并加以分析,咱们运行函数。
呈现了咱们想要的 OOM,咱们复制一条垃圾收集信息来剖析一下:
[GC (Allocation Failure)
[PSYoungGen: 269254K->776K(304640K)]
这条日志示意 GC 前 young 区和 GC 后 young 区的内存大小区别,GC 前:269254 GC 后:776
670669K->459534K(1000960K), 0.0303594 secs]
这条日志示意堆的总内存大小 ,GC 前 670669,GC 后 459534K
[Times: user=0.05 sys=0.03, real=0.03 secs]
这条示意执行工夫。
再来看一条 Full GC
[Full GC (Ergonomics)
[PSYoungGen: 235302K->0K(304640K)]
同上,年老代收集状况
[ParOldGen: 688134K->344783K(696320K)] 923437K->344783K(1000960K),
老年代收集状况
[Metaspace: 3263K->3263K(1056768K)], 0.0394456 secs]
永恒代收集状况
[Times: user=0.13 sys=0.02, real=0.04 secs]
耗时
总结:
明天咱们介绍了堆的构造,以及 GC 过程以及调优参数,咱们能够尝试入手地调试一下 JVM 参数,尽管这只是一些简略的调参。然而通过一直地练习,由浅入深由易到难,咱们最初都会把握 JVM 调优!