美文网首页
两个奇怪的GC日志解析

两个奇怪的GC日志解析

作者: cocalrush | 来源:发表于2017-07-02 10:02 被阅读0次

前段时间有空学习了下GC内存的分配和回收,期间遇到两次非常奇怪的GC日志,这里记录入下。

//-Xms10M -Xmx10M  -Xmn3M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:+PrintCommandLineFlags
启动的参数 分配最大10M的堆 年轻代3M
程序运行每次也分需要3M的内存
        final int oneMB = 1* 1024 * 1024;
        int count = 0;
        while(true) {
            for (int i = 1; i < 100; i++) {
                byte[] b = new byte[oneMB * 3];
                System.out.println(" --- " + i);
                Thread.sleep(1000*1);

            }
        }

--- 1
--- 2
[GC (Allocation Failure) [PSYoungGen: 731K->432K(2560K)] 6875K->6584K(9728K), 0.0018651 secs] [Times: user=0.01 sys=0.00, real=0.00 secs]
[GC (Allocation Failure) [PSYoungGen: 432K->400K(2560K)] 6584K->6552K(9728K), 0.0021875 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
[Full GC (Allocation Failure) [PSYoungGen: 400K->0K(2560K)] [ParOldGen: 6152K->338K(7168K)] 6552K->338K(9728K), [Metaspace: 2649K->2649K(1056768K)], 0.0065318 secs] [Times: user=0.01 sys=0.00, real=0.00 secs]
--- 3
--- 4
[GC (Allocation Failure) [PSYoungGen: 40K->0K(2560K)] 6523K->6482K(9728K), 0.0013011 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC (Allocation Failure) [PSYoungGen: 0K->0K(2560K)] 6482K->6482K(9728K), 0.0011310 secs] [Times: user=0.01 sys=0.00, real=0.00 secs]
[Full GC (Allocation Failure) [PSYoungGen: 0K->0K(2560K)] [ParOldGen: 6482K->327K(7168K)] 6482K->327K(9728K), [Metaspace: 2649K->2649K(1056768K)], 0.0052355 secs] [Times: user=0.01 sys=0.00, real=0.01 secs]
--- 5

--1 就是一次分配内存
可以看到第三次的分配内存的时候产生了2次YongGC,当时我非常奇怪还以为遇到了BUG。 现在想起来应该是参数设置的问题。 年轻代的内存和程序所需要分配的内存大小相当。前面两次直接因为年代不足从老年代分配了。第三次的时候老年代已经不能满足,所以先执行一次YGC 回收一下,发现还是不足,但是可能经过某种运算(这只是猜测)认为年轻代再回收一次还是能满足。 所以有回收了一次。 发现还是不能满足最后进行了一次FULL GC。
正常情况下 生产上应该不会出现这种问题 因为生产上年轻代的内存肯定是远远大于程序需要分配的内存,不过连续两次YGC还是不是特别清楚,到底是因为一种补偿机制还是因为算法原因。

第二个比较神奇的日志是
这次我们正常设置启动参数

-Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:+PrintCommandLineFlags
堆的大小为20M 年轻代10M

    
       final int oneMB = 1* 1024 * 1024;
        List<byte[]> l = new ArrayList<>(6); //这次为例测老年年回收 用一个list来装备引用对象
        int count = 0;
        while(true) {
            for (int i = 1; i < 100; i++) {
                byte[] b = new byte[oneMB * 1]; //每次分配1M
                System.out.println(" --- " + i);
                l.add(b);
                if (l.size() > 5) { //快满的时候释放掉内存
                    l.clear();
                    System.out.println(" --- " + i + "clear");
                }
                Thread.sleep(1000*1);
            }
        }

大概运行20多秒后
--- 20
--- 21
[GC (Allocation Failure) [PSYoungGen: 7940K->368K(9216K)] 11020K->6520K(19456K), 0.0046196 secs] [Times: user=0.01 sys=0.00, real=0.00 secs]
--- 22
--- 23
--- 24
--- 24clear
--- 25
--- 26
--- 27
--- 28
[GC (Allocation Failure) --[PSYoungGen: 7695K->7695K(9216K)] 13847K->16919K(19456K), 0.0050605 secs] [Times: user=0.01 sys=0.00, real=0.00 secs]
[Full GC (Ergonomics) [PSYoungGen: 7695K->0K(9216K)] [ParOldGen: 9224K->4411K(10240K)] 16919K->4411K(19456K), [Metaspace: 2650K->2650K(1056768K)], 0.0081017 secs] [Times: user=0.02 sys=0.00, real=0.01 secs]
--- 29

我们知道正常情况下YGC多是 7940K->368K(9216K) 这种变少的。
出现这种13847K->16919K(19456K), 不是很诡异吗。
当时堆内存状态为(500ms打印一次)

jstat -gcutil 38508 500 100
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
0.00 39.06 76.94 60.16 54.48 56.16 3 0.007 0 0.000 0.007
0.00 39.06 89.45 60.16 54.48 56.16 3 0.007 0 0.000 0.007
0.00 39.06 89.45 60.16 54.48 56.16 3 0.007 0 0.000 0.007
0.00 0.00 14.45 43.08 54.49 56.16 4 0.011 1 0.004 0.015
0.00 0.00 14.45 43.08 54.49 56.16 4 0.011 1 0.004 0.015

可以看到当时S1区有39.06的内容。 这次YGC正在将S1的内容拷贝到OLD区 但是因为当时内存碎片或者其他原因 达到old区可以用的内存占比?,导致old区的内存也不太够了 这次促发了一次fullGC然后回收了年轻代的内存。 所以出现了这条诡异的日志吧。

相关文章

  • 两个奇怪的GC日志解析

    前段时间有空学习了下GC内存的分配和回收,期间遇到两次非常奇怪的GC日志,这里记录入下。 --- 1--- 2[G...

  • Java GC日志分析

    1. 查看GC日志准备 2. 年轻代GC日志 3. CMS GC日志 4. CMS GC 7阶段解析 1.初始标记...

  • 通过 gc.log 调优 JVM

    一、GC 日志查看 GC 日志默认是关闭的,需要查看 GC 日志首先需要开启 GC 日志。 常用 GC 日志的配置...

  • JAVA学习笔记--GC日志解析

    JAVA学习笔记--GC日志解析 https://my.oschina.net/u/2269952/blog/53...

  • JVM - GC日志

    JVM - GC日志 -XX:+PrintGC 输出GC日志 -XX:+PrintGCDetails 输出GC的详...

  • JVM GC日志文件分析

    JVM GC日志文件分析 GC 是垃圾回收(Garbage Collection)的缩写。两个关键名词:垃圾...

  • java GC日志解析

    java GC详解 关键词: 结论:

  • 奇怪的GC (Allocation Failure)日志

    今天在玩JVM的GC日志时,遇到了一个奇怪的现象。目前的知识还没找到原因,先记录下。找到原因有再补充~。 环境是:...

  • GC日志查看和分析

    GC日志查看和分析 GC日志查看 可以通过在java命令种加入参数来指定对应的gc类型,打印gc日志信息并输出至文...

  • JVM GC 日志详解

    JVM GC 日志详解 本文采用的JDK版本: 一、GC 日志参数 设置JVM GC格式日志的主要参数包括如下8个...

网友评论

      本文标题:两个奇怪的GC日志解析

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