GC的常用参数使用

java中的对象都创建在堆中,当堆中的对象所占空间到一定量后,就需要清除掉死亡对象,垃圾回收是JVM自动完成的,不用码农手动清理,但偶尔想看看对象所占的堆空间或GC的具体过程,就需要借助GC日志了。

一、打印GC日志

1、示例程序
程序1
public class GCTest {
    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            byte[] b = new byte[1*1024*1024];
        }
    }
}
2、加VM参数 -XX:+PrintGCDetail(以idea为例)
-XX:+PrintGCDetails

最后记得点击下面的apply和ok,然后运行GCTest,就可以看到:对象都放在eden区48%(10M)的空间,目前没有发生GC,所以Survivor区和年老代都是0%。

3、调整GCTest创建的对象大小为30M
程序2
public class GCTest {
    public static void main(String[] args) {
        for (int i = 0; i < 30; i++) {
            byte[] b = new byte[1*1024*1024];
        }
    }
}

再次运行,可以看到发生了一次GC,将幸存的对象移至Survivor from区,所以eden、from都有对象存在了。


GC日志:[GC (Allocation Failure) [PSYoungGen: 32978K->1512K(38400K)] 32978K->1520K(125952K), 0.0020363 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
可以看出新生代 YoungGen 分配失败,32978K->1512K(38400K) 表示 GC 前已使用->GC后已使用(该区域总容量),[]之外表示Java堆GC前已使用->GC后已使用(Java堆总容量),最后为 GC 耗时。

4、-XX:+PrintHeapAtGC

-XX:+PrintHeapAtGC的含义是打印GC前后的详细堆栈信息
将它配置在VM options中,运行程序2,就可以看到:

5、-XX:+TraceClassLoading

-XX:+TraceClassLoading的作用是监控类的加载
将它配置在VM options中,运行程序2,就可以看到:
将它配置在VM参数中,运行程序2,就可以看到:

二、堆分配参数

程序3
public class TestMaxMinHeap {
    private static final int M = 1024 * 1024;
    public static void main(String[] args) {
        System.out.println("maxMemory:" + ( Runtime.getRuntime().maxMemory()/M) + "M");
        System.out.println("freeMemory:" + (Runtime.getRuntime().freeMemory()/M) + "M");
        System.out.println("totalMemory:" + (Runtime.getRuntime().totalMemory()/M) + "M");
    }
}

不加任何参数的时候,运行结果是:

1、-Xmx 和 -Xms

-Xmx是最大堆大小,默认值是物理内存的1/4(<1GB),
-Xmx20m 设置 maxMemory 为 20 M,分配空间不能超过最大堆内存大小,否则会抛出 OutofMemory 异常

-Xmx20m

-Xms是初始堆大小,默认值是物理内存的1/64(<1GB),-Xms20m 设置 total Memory 为 20 M ,totalMemory 就是初始化堆大小,它的意思是一开始限定堆大小为多少,如果不够则可以扩充,但必须小于最大堆大小。

-Xms20m
2、测试动态调整

①首先设置 -Xmx20m -Xms5m ,最大堆空间20m,初始大小5m。

-Xmx20m -Xms5m

②分配2M

程序4
public class TestMaxMinHeap {
    private static final int M = 1024 * 1024;
    public static void main(String[] args) {
        byte b[] = new byte[2 * M];
        System.out.println("maxMemory:" + ( Runtime.getRuntime().maxMemory()/M) + "M");
        System.out.println("freeMemory:" + (Runtime.getRuntime().freeMemory()/M) + "M");
        System.out.println("totalMemory:" + (Runtime.getRuntime().totalMemory()/M) + "M");
    }
}
分配2M

③分配6M

程序5
public class TestMaxMinHeap {
    private static final int M = 1024 * 1024;
    public static void main(String[] args) {
        byte b[] = new byte[6 * M];
        System.out.println("maxMemory:" + ( Runtime.getRuntime().maxMemory()/M) + "M");
        System.out.println("freeMemory:" + (Runtime.getRuntime().freeMemory()/M) + "M");
        System.out.println("totalMemory:" + (Runtime.getRuntime().totalMemory()/M) + "M");
    }
}
分配6M

③分配30M

程序6
public class TestMaxMinHeap {
    private static final int M = 1024 * 1024;
    public static void main(String[] args) {
        byte b[] = new byte[30 * M];
        System.out.println("maxMemory:" + ( Runtime.getRuntime().maxMemory()/M) + "M");
        System.out.println("freeMemory:" + (Runtime.getRuntime().freeMemory()/M) + "M");
        System.out.println("totalMemory:" + (Runtime.getRuntime().totalMemory()/M) + "M");
    }
}
分配30M
2、-Xmn

-Xmn:设置 新生代 大小

①新生代大小设置为 2M,-Xmn2m -Xms20m -Xmx20m -XX:+PrintGCDetails

程序7
public class TestNewSpace {
    private static final int M = 1024*1024;
    public static void main(String[] args) {
        byte[] b = null;
        for (int i = 0; i < 10; ++i) {
            b = new byte[1*M];
        }
    }
}
-Xmn2m

②设置新生代为18M,-Xmn18m -Xms20m -Xmx20m -XX:+PrintGCDetails

-Xmn18m
3、-SurvivorRatio

-SurvivorRatio:设置新生代中 Eden space 和 Survivor space 的大小

①设置新生代8m,-Xmn8m -Xms20m -Xmx20m -XX:+PrintGCDetails

-Xmn8m

②将新生代中的的Survivor设置大一点,-Xmn8m -Xms20m -Xmx20m -XX:+PrintGCDetails -XX:SurvivorRatio=2

-XX:SurvivorRatio=2
4、-XX:NewRatio

-XX:NewRatio 设置年老代和年轻代的比值

①设置年老代和年轻代的比例是2:1
-Xms20m -Xmx20m -XX:+PrintGCDetails -XX:NewRatio=2

-XX:NewRatio=2

②设置年老代和年轻代的比例是3:1
-Xms20m -Xmx20m -XX:+PrintGCDetails -XX:NewRatio=3


-XX:NewRatio=3
5、-Xss

-Xss设置每个线程的堆栈大小

①设置线程栈为128K,-Xss128k

程序8
public class TestXssStack {
    public static int count = 0;
    public static void func() {
        count++;
        func();
    }
    public static void main(String[] args) {
        try {
            func();
        }catch (Throwable e){
            System.out.println("count:" + count);
        }
    }
}
-Xss128k

②设置线程栈为1m,-Xss1m

-Xss1m

总结

本篇主要简单介绍了如何使用idea查看GC日志,以及JVM参数-XX:+PrintGCDetail、-XX:+PrintHeapAtGC、-XX:+TraceClassLoading、-Xmx 、-Xms、-Xmn、-SurvivorRatio、-XX:NewRatio、-Xss所代表的意义和使用。

你可能感兴趣的:(GC的常用参数使用)