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/64System.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调优!