基于JDK8的JVM参数设置和GC日志解读

一、在IDEA中设置程序的运行参数

Run -> Edit Configuration 

基于JDK8的JVM参数设置和GC日志解读_第1张图片

-XX:+PrintGCDetails
-Xms30M
-Xmx30M
-Xmn10M
-XX:SurvivorRatio=8

参数含义分别是:

打印GC日志

最小堆内存

最大堆内存

堆中新生代内存

新生代内存中Eden和Survivor大小之比,如果为8表示Eden占80%,另外两个Survivor各占10%

二、运行程序

package memory.gc;

/**
 * Created by Administrator on 2018-04-11.
 */
public class GCLogTest {

    public static void main(String[] args) {
        System.out.println(Runtime.getRuntime().maxMemory());
        System.out.println(Runtime.getRuntime().totalMemory());
        Object obj = new Object();
        obj = null;
        System.gc();
    }

}

程序通过System.gc()使JVM进行了一次Full GC

看到输出的日志如下

30408704
30408704
[Full GC (System.gc()) [TenuredDisconnected from the target VM, address: '127.0.0.1:55874', transport: 'socket'
: 0K->528K(20480K), 0.0029772 secs] 1315K->528K(29696K), [Metaspace: 1840K->1840K(4480K)], 0.0030434 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
Heap
 def new generation   total 9216K, used 82K [0x03800000, 0x04200000, 0x04200000)
  eden space 8192K,   1% used [0x03800000, 0x03814928, 0x04000000)
  from space 1024K,   0% used [0x04000000, 0x04000000, 0x04100000)
  to   space 1024K,   0% used [0x04100000, 0x04100000, 0x04200000)
 tenured generation   total 20480K, used 528K [0x04200000, 0x05600000, 0x05600000)
   the space 20480K,   2% used [0x04200000, 0x04284308, 0x04284400, 0x05600000)
 Metaspace       used 1845K, capacity 2242K, committed 2368K, reserved 4480K

[Full GC : 这是Full GC的标识。

先忽略上面中括号[Full GC ..... ]之间的信息(里面有回收时间sec、回收前->回收后大小),

直接看Heap下面的输出日志:

def new generation total 9216k 说明新生代垃圾回收内存区域总大小为9216k。

这个大小是怎么算出来的呢?

它是:eden space 加上一个 survivor space (也就是from space)的大小,另外一个survivor space (也就是to space)是用来通过复制算法存放存活对象的,不在回收区域之内,所以def new generation total 没有算上它。

基于JDK8的JVM参数设置和GC日志解读_第2张图片

对应新生代内存Xmn的大小正好是10M。其中eden space和survivor space(from space 和 to space任意一个)之比8:1。


tenured generation表示老年代内存,20M,加上新生代内存10M,正好30M。



元空间(metaspace)

持久代的空间在JDK8中被彻底地删除后(JDK7没有彻底删除),它被一个叫元空间的区域所替代了。

这样JVM会忽略PermSize和MaxPermSize这两个参数(经过试验,确实如此),还有就是再也看不到java.lang.OutOfMemoryError: PermGen error的异常了。


JDK 8的HotSpot JVM现在使用的是本地内存来表示类的元数据,这个区域就叫做元空间。



你可能感兴趣的:(JVM)