zoukankan      html  css  js  c++  java
  • java垃圾回收诡异现象

    在知乎上看到一篇提问,于是做了个实验帮助他解答,这里整理成一篇文章分享一下。

    先看代码如下代码:

     1 /**
     2  * Created on 2017/12/16.
     3  *
     4  * -verbose:gc -XX:+UseSerialGC -Xms6M -Xmx6M -Xmn2M -XX:+PrintGCDetails
     5  */
     6 public class TestHeap {
     7     private static final int _1MB = 1024*1024;
     8 
     9     public static void main(String[] args) throws Exception{
    10         byte[] b = new byte[3*_1MB];
    11     }
    12 }

    运行时加上注释里的JVM参数,控制台打印如下

    问题是:分配一个3m的数组,新生代只有2m,所以对象直接分配到年老代。通过打印结果也可以看出来,年老代用了3072k,正好是我们的3m数组。但是为什么新生代居然还有68%不占用呢?

    简单猜想一下,肯定是Java在运行时自己创建了一些对象占用了新生代空间。好我们来验证下。

    将代码为什么也不做:

    /**
     * Created on 2017/12/16.
     *
     * -verbose:gc -XX:+UseSerialGC -Xms6M -Xmx6M -Xmn2M -XX:+PrintGCDetails
     */
    public class TestHeap {
        private static final int _1MB = 1024*1024;
    
        public static void main(String[] args) throws Exception{
            //byte[] b = new byte[3*_1MB];
        }
    }

    控制台打印如下:

    即使执行创建字节数组语句,新生代依旧被占用68%。可以说我们假象成立。

    不信?

    那好吧,咱们就打印下此时Java堆空间里的对象来看看。

     咱们是用jmap命令来打印出堆里的对象看看,顺便复习下jmap的使用。

    我们使用如下命令:

    jmap -histo:live pid 

    注意:此命令不能在线上执行,因为会触发JVM的fullgc。

    代码不变,依旧是注释掉字节数组的创建语句。只不过为了方便执行jmap命令,咱们让它暂停下,以防进程退出。 

    /**
     * Created on 2017/12/16.
     *
     * -verbose:gc -XX:+UseSerialGC -Xms6M -Xmx6M -Xmn2M -XX:+PrintGCDetails
     */
    public class TestHeap {
        private static final int _1MB = 1024*1024;
    
        public static void main(String[] args)throws Exception{
            //byte[] b = new byte[3*_1MB];
            Thread.sleep(100000L);
        }
    }

    执行jmap命令结果如下(部分截图):

     

    看到了,我们啥都不做都有1544个char数组对象,120个byte数组对象等等。

    ---------------------------------------------------------------------------------------------------------------------

    这里是跟阿里的技术大牛创建的一个圈子,主要面向初学者提供辅导帮助。有兴趣的可以加入。

    https://t.xiaomiquan.com/aEQVNJe

  • 相关阅读:
    如何简单的理解LSTM——其实没有那么复杂(转载)
    关于梯度爆炸和梯度消失的详解(转载)
    通俗易懂---反向传播(转载)
    pandas读取csv文件中文乱码问题
    python安装imblearn(PackageNotFoundError: ''Package missing in current channels")
    python中的虚拟环境(在jupyter和pycharm中的使用)
    关于阻塞/非阻塞、同步/非同步、死锁
    关于synchronize与lock的区别
    为什么volatile能保证有序性不能保证原子性
    索引以及Mysql中的索引
  • 原文地址:https://www.cnblogs.com/qingquanzi/p/8046042.html
Copyright © 2011-2022 走看看