JVM-GC总结-配置实战--第三发

26 篇文章 0 订阅

配置举例1:

vm args: 
-Xms60m -Xmx60m -XX:NewRatio=2 -XX:SurvivorRatio=3 -XX:MaxPermSize=30m -XX:MaxTenuringThreshold=3 -XX:+PrintHeapAtGC

使用工具:jvisualvm (安装visual gc 插件) 
这里写图片描述
根据设置堆内存为60m, 因为设置了-XX:NewRatio=2所以年轻代与年老代的比例是1:2, 
年轻代 20m,年老代40m, 设置-XX:SurvivorRatio=3 所以 survivor与eden的比例是1:3, 
Eden占年轻代的3/5是12m,s0,s1各占1/5是4m,从图中可以看到jvm内存分布符合设置的参数,方法区(非堆)30m. 
此时程序刚运行,dump了一下堆,可以看到刚生成的好多对象都是jmx相关的对象 
这里写图片描述

运行代码每次增加1m的对象到内存,当eden无法创建时会触发一次minor gc, 
这时由于survivor区无法承载eden中的全部对象,所以对象直接进入了老年代, 
见图: 
这里写图片描述
Eden中的对象一部分进入了s0,另一部分直接进入了年老代. 
这里写图片描述
上图,再次增加对象到eden,触发了一次minor gc,此时s1无法存放eden中的全部存活对象和s0中的存活对象, 老年代此时承担了内存担保的角色存放了多余的对象. 
这里写图片描述
上图中,由于程序中对象一直是存活的无法回收所以会一直进入老年代无法gc回收掉.

这里写图片描述
上图中老年代已满无法继续存放对象,此时full gc 有无法回收掉对象所以会报出

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
堆内存溢出,程序退出.
看一下最后一次gc时堆中前后的数据对比:
{Heap before GC invocations=9 (full 5):
 PSYoungGen      total 16384K, used 11264K [0x00000000fec00000, 0x0000000100000000, 0x0000000100000000)
  eden space 12288K, 91% used [0x00000000fec00000,0x00000000ff7001d0,0x00000000ff800000)
  from space 4096K, 0% used [0x00000000ffc00000,0x00000000ffc00000,0x0000000100000000)
  to   space 4096K, 0% used [0x00000000ff800000,0x00000000ff800000,0x00000000ffc00000)
 PSOldGen        total 40960K, used 40572K [0x00000000fc400000, 0x00000000fec00000, 0x00000000fec00000)
  object space 40960K, 99% used [0x00000000fc400000,0x00000000feb9f1e0,0x00000000fec00000)
 PSPermGen       total 21248K, used 8605K [0x00000000fa600000, 0x00000000fbac0000, 0x00000000fc400000)
  object space 21248K, 40% used [0x00000000fa600000,0x00000000fae677a0,0x00000000fbac0000)
Heap after GC invocations=9 (full 5):
 PSYoungGen      total 16384K, used 11264K [0x00000000fec00000, 0x0000000100000000, 0x0000000100000000)
  eden space 12288K, 91% used [0x00000000fec00000,0x00000000ff7001d0,0x00000000ff800000)
  from space 4096K, 0% used [0x00000000ffc00000,0x00000000ffc00000,0x0000000100000000)
  to   space 4096K, 0% used [0x00000000ff800000,0x00000000ff800000,0x00000000ffc00000)
 PSOldGen        total 40960K, used 40538K [0x00000000fc400000, 0x00000000fec00000, 0x00000000fec00000)
  object space 40960K, 98% used [0x00000000fc400000,0x00000000feb969f8,0x00000000fec00000)
 PSPermGen       total 21248K, used 8537K [0x00000000fa600000, 0x00000000fbac0000, 0x00000000fc400000)
  object space 21248K, 40% used [0x00000000fa600000,0x00000000fae56550,0x00000000fbac0000)
}

此次测试代码:

public class JConsoleTest {
    /**
     * 内存占位符对象 大约64k
     */
    static class ConObj{

        public byte[] placeholder = new byte[1024 * 1024];
    }


    public static void fillHeap(int num) throws InterruptedException {
        List<ConObj> list = new ArrayList<ConObj>();
        for(int i = 0;i < num;i++){
            Thread.sleep(500);
            list.add(new ConObj());
        }

        //由于方法未执行完毕 list尚在作用域中 此时 执行gc 会导致回收不掉
        //System.gc();

    }
    /**
     * 设置实例:
     *   1)vm args:
     *    -Xms1024m -Xmx1024m -XX:NewRatio=4 -XX:SurvivorRatio=4  -XX:MaxPermSize=16m
     *
     *   2)vm args:
     *    -Xms60m -Xmx60m -XX:NewRatio=2 -XX:SurvivorRatio=3  -XX:MaxPermSize=30m -XX:MaxTenuringThreshold=3 -XX:+PrintHeapAtGC
     *
     * 演示jconsole的内存页签  观察 eden survivor
     * vm args: -Xms100m -Xmx100m -XX:+UseSerialGC
     * @param args
     * @throws InterruptedException
     */
    public static void main(String[] args) throws InterruptedException {
        Thread.sleep(30000);
        fillHeap(100);
        //可以回收掉
        System.gc();
        fillHeap(100);
        fillHeap(100);
        System.gc();
        synchronized (JConsoleTest.class){
            JConsoleTest.class.wait();
        }
    }
}

配置举例2

  -Xmx60m -Xms60m -Xmn30m -XX:+UseConcMarkSweepGC -XX:+UseParNewGC   -XX:MaxTenuringThreshold=3   -XX:+PrintGCApplicationStoppedTime -XX:+PrintHeapAtGC
  • 1

这里写图片描述

根据配置jvm堆大小为60m,其中分配给年轻代30m,年轻代中eden和s0,s1的比例默认是8:1, eden 24m,s0,s1各3m, 
这里写图片描述

上图第一次触发minor gc,同1老年代内存担保承担,很多对象没有经过survivor直接进入了老年代 
第一次minor gc的堆前后对比:

{Heap before GC invocations=0 (full 0):
 par new generation   total 27648K, used 24576K [0x00000000f7200000, 0x00000000f9000000, 0x00000000f9000000)
  eden space 24576K, 100% used [0x00000000f7200000, 0x00000000f8a00000, 0x00000000f8a00000)
  from space 3072K,   0% used [0x00000000f8a00000, 0x00000000f8a00000, 0x00000000f8d00000)
  to   space 3072K,   0% used [0x00000000f8d00000, 0x00000000f8d00000, 0x00000000f9000000)
 concurrent mark-sweep generation total 30720K, used 0K [0x00000000f9000000, 0x00000000fae00000, 0x00000000fae00000)
 concurrent-mark-sweep perm gen total 21248K, used 8687K [0x00000000fae00000, 0x00000000fc2c0000, 0x0000000100000000)
Heap after GC invocations=1 (full 0):
 par new generation   total 27648K, used 3007K [0x00000000f7200000, 0x00000000f9000000, 0x00000000f9000000)
  eden space 24576K,   0% used [0x00000000f7200000, 0x00000000f7200000, 0x00000000f8a00000)
  from space 3072K,  97% used [0x00000000f8d00000, 0x00000000f8fefd98, 0x00000000f9000000)
  to   space 3072K,   0% used [0x00000000f8a00000, 0x00000000f8a00000, 0x00000000f8d00000)
 concurrent mark-sweep generation total 30720K, used 8194K [0x00000000f9000000, 0x00000000fae00000, 0x00000000fae00000)
 concurrent-mark-sweep perm gen total 21248K, used 8687K [0x00000000fae00000, 0x00000000fc2c0000, 0x0000000100000000)
}   

第一次minor gc 应用暂停时间: 
Total time for which application threads were stopped: 0.0215440 seconds – 21.5ms 
这里写图片描述
上图是通过System.gc()触发了一次full gc之后的jvm内存分布. 
下面是full gc 前后heap前后对比:

{Heap before GC invocations=1 (full 0):
 par new generation   total 27648K, used 17646K [0x00000000f7200000, 0x00000000f9000000, 0x00000000f9000000)
  eden space 24576K,  59% used [0x00000000f7200000, 0x00000000f804bb48, 0x00000000f8a00000)
  from space 3072K,  97% used [0x00000000f8d00000, 0x00000000f8fefd98, 0x00000000f9000000)
  to   space 3072K,   0% used [0x00000000f8a00000, 0x00000000f8a00000, 0x00000000f8d00000)
 concurrent mark-sweep generation total 30720K, used 8194K [0x00000000f9000000, 0x00000000fae00000, 0x00000000fae00000)
 concurrent-mark-sweep perm gen total 21248K, used 8703K [0x00000000fae00000, 0x00000000fc2c0000, 0x0000000100000000)
Heap after GC invocations=2 (full 1):
 par new generation   total 27648K, used 0K [0x00000000f7200000, 0x00000000f9000000, 0x00000000f9000000)
  eden space 24576K,   0% used [0x00000000f7200000, 0x00000000f7200000, 0x00000000f8a00000)
  from space 3072K,   0% used [0x00000000f8d00000, 0x00000000f8d00000, 0x00000000f9000000)
  to   space 3072K,   0% used [0x00000000f8a00000, 0x00000000f8a00000, 0x00000000f8d00000)
 concurrent mark-sweep generation total 30720K, used 923K [0x00000000f9000000, 0x00000000fae00000, 0x00000000fae00000)
 concurrent-mark-sweep perm gen total 21248K, used 8698K [0x00000000fae00000, 0x00000000fc2c0000, 0x0000000100000000)
}

应用暂停时间: 
Total time for which application threads were stopped: 0.0292275 seconds – 29ms

继续添加对象触发minor gc 
![这里写图片描述](https://img-blog.csdn.net/201504231118209{Heap before GC invocations=2 (full 1): 
par new generation total 27648K, used 24576K [0x00000000f7200000, 0x00000000f9000000, 0x00000000f9000000) 
eden space 24576K, 100% used [0x00000000f7200000, 0x00000000f8a00000, 0x00000000f8a00000) 
from space 3072K, 0% used [0x00000000f8d00000, 0x00000000f8d00000, 0x00000000f9000000) 
to space 3072K, 0% used [0x00000000f8a00000, 0x00000000f8a00000, 0x00000000f8d00000) 
concurrent mark-sweep generation total 30720K, used 923K [0x00000000f9000000, 0x00000000fae00000, 0x00000000fae00000) 
concurrent-mark-sweep perm gen total 21248K, used 8711K [0x00000000fae00000, 0x00000000fc2c0000, 0x0000000100000000) 
Heap after GC invocations=3 (full 1): 
par new generation total 27648K, used 395K [0x00000000f7200000, 0x00000000f9000000, 0x00000000f9000000) 
eden space 24576K, 0% used [0x00000000f7200000, 0x00000000f7200000, 0x00000000f8a00000) 
from space 3072K, 12% used [0x00000000f8a00000, 0x00000000f8a62f30, 0x00000000f8d00000) 
to space 3072K, 0% used [0x00000000f8d00000, 0x00000000f8d00000, 0x00000000f9000000) 
concurrent mark-sweep generation total 30720K, used 923K [0x00000000f9000000, 0x00000000fae00000, 0x00000000fae00000) 
concurrent-mark-sweep perm gen total 21248K, used 8711K [0x00000000fae00000, 0x00000000fc2c0000, 0x0000000100000000) 
}or gc 回收了eden中的大部分对象. 
程序暂停时间: 
Total time for which application threads were stopped: 0.0039866 seconds 
配置2代码:

public class JConsoleTest {
    /**
     * 内存占位符对象 大约64k
     */
    static class ConObj{

        public byte[] placeholder = new byte[1024 * 1024];
    }
    public static void fillHeap(int num) throws InterruptedException {
        List<ConObj> list = new ArrayList<ConObj>();
        for(int i = 0;i < num;i++){
            Thread.sleep(500);
            list.add(new ConObj());
        }
        //由于方法未执行完毕 list尚在作用域中 此时 执行gc 会导致回收不掉
        //System.gc();

    }
    /**
     * 设置实例:
     *   1)vm args:
     *    -Xms1024m -Xmx1024m -XX:NewRatio=4 -XX:SurvivorRatio=4  -XX:MaxPermSize=16m
     *
     *   2)vm args:
     *    -Xms60m -Xmx60m -XX:NewRatio=2 -XX:SurvivorRatio=3  -XX:MaxPermSize=30m -XX:MaxTenuringThreshold=3 -XX:+PrintHeapAtGC
     *
     *   3) vm args:
     *      -Xmx60m -Xms60m -Xmn30m -XX:+UseConcMarkSweepGC -XX:+UseParNewGC   -XX:MaxTenuringThreshold=3   -XX:+PrintGCApplicationStoppedTime -XX:+PrintHeapAtGC
     * 演示jconsole的内存页签  观察 eden survivor
     * vm args: -Xms100m -Xmx100m -XX:+UseSerialGC
     * @param args
     * @throws InterruptedException
     */
    public static void main(String[] args) throws InterruptedException {
        Thread.sleep(15000);
        fillHeap(20);
        //可以回收掉
        System.gc();
        fillHeap(20);
        fillHeap(5);
        fillHeap(20);
        System.gc();
        synchronized (JConsoleTest.class){
            JConsoleTest.class.wait();
        }
    }
}

上述是俩个较为简单的jvm参数配置演示.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值