美文网首页
GC的常用参数使用

GC的常用参数使用

作者: 少博先生 | 来源:发表于2018-03-31 19:25 被阅读0次

    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的常用参数使用

          本文链接:https://www.haomeiwen.com/subject/iatwcftx.html