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

先看代码如下代码:

 /**
* 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];
}
}

运行时加上注释里的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

jvm内存回收诡异现象的更多相关文章

  1. JVM内存回收机制简述

    JVM内存回收机制涉及的知识点太多了,了解越多越迷糊,汗一个,这里仅简单做个笔记,主要参考<深入理解Java虚拟机:JVM高级特性与最佳实践(第二版)> 目前java的jdk默认虚拟机为H ...

  2. Java基础-JVM内存回收

    Sun的JVMGenerationalCollecting(垃圾回收)原理是这样的:把对象分为年青代(Young).年老代(Tenured).持久代(Perm),对不同生命周期的对象使用不同的算法.( ...

  3. JVM内存回收机制

    1. JVM内存回收机制简述 http://www.cnblogs.com/lzrabbit/p/3826738.html

  4. JVM内存回收机制——哪些内存需要被回收(JVM学习系列2)

    上一篇文章中讨论了Java内存运行时的各个区域,其中程序计数器.虚拟机栈.本地方法栈随线程生灭,且创建时需要多少内存,基本上在译期间就决定的了,所以在内存回收时无需特殊的关注.而堆和方法区则不同,首先 ...

  5. K8S(18)容器环境下资源限制与jvm内存回收

    K8S(18)容器环境下资源限制与jvm内存回收 目录 K8S(18)容器环境下资源限制与jvm内存回收 一.k8s中的java资源限制与可能的问题 方案1:通过JVM的Xms和Xmx参数限制 方案2 ...

  6. JVM内存回收对象及引用分析

    自动垃圾回收是Java相较于C++的一个重要的特点,想了解JVM的垃圾回收机制,首先我们要知道垃圾回收是回收什么地方的垃圾,我在我的上一篇博客<JVM内存区域划分>里面有写到JVM里面的内 ...

  7. JVM内存回收区域+对象存活的判断+引用类型+垃圾回收线程

    此文已由作者赵计刚薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 注意:本文主要参考自<深入理解Java虚拟机(第二版)> 说明:查看本文之前,推荐先知道JVM ...

  8. 第三章 JVM内存回收区域+对象存活的判断+引用类型+垃圾回收线程

    注意:本文主要参考自<深入理解Java虚拟机(第二版)> 说明:查看本文之前,推荐先知道JVM内存结构,见<第一章 JVM内存结构> 1.内存回收的区域 堆:这是GC的主要区域 ...

  9. Java jvm 内存回收机制

    http://blog.csdn.net/yaerfeng/article/details/51291903 在Java中,它的内存管理包括两方面:内存分配(创建Java对象的时候)和内存回收,这两方 ...

随机推荐

  1. 轻松学会ES6新特性之生成器

    生成器虽然是ES6最具魔性的新特性,但也是最难懂得的一节,笔者写了大量的实例来具体化这种抽象的概念,能够让人一看就懂,目的是希望别人不要重复或者减少笔者学习生成器的痛苦经历. 在说具体的ES6生成器之 ...

  2. KiKi's K-Number

    KiKi's K-Number Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tot ...

  3. Hive中常用的查询命令

    日志数据的统计处理在这里反倒没有什么特别之处,就是一些 SQL 语句而已,也没有什么高深的技巧,不过还是列举一些语句示例,以示 hive 处理数据的方便之处,并展示 hive 的一些用法. a)    ...

  4. js 作用域,作用域链,闭包

    什么是作用域? 作用域是一种规则,在代码编译阶段就确定了,规定了变量与函数的可被访问的范围.全局变量拥有全局作用域,局部变量则拥有局部作用域. js是一种没有块级作用域的语言(包括if.for等语句的 ...

  5. [eclipse相关] eclipse 安装svn插件

    最近看到别人带主题的eclipse,非常羡慕,所以也换了一个eclipse,版本是java ee luna 4.4.2,然后得偿所愿有了花花绿绿的代码界面:) 但是差点被svn搞死,~~~~(> ...

  6. 使用SQLPLUS创建用户名和表空间

    用sqlplus为oracle创建用户和表空间用sqlplus为oracle创建用户和表空间用Oracle10g自带的企业管理器或PL/SQL图形化的方法创建表空间和用户以及分配权限是相对比较简单的, ...

  7. 用UiPath导入RPA实践1:VirtualBox的安装

      之前说了关于RPA的一些概念,但对于RPA到底是个什么东西,能干什么,咋么干都没有具体的概念,所以后面分几回,用[UiPath]这个工具为基础说说RPA的实际应用,希望能抛砖引玉. 在试用新的东西 ...

  8. SVN服务迁移备份操作步骤

    SVN服务备份操作步骤 1.准备源服务器和目标服务器 源服务器:192.168.1.250 目标服务器:192.168.1.251 root/rootroot 2.对目标服务器(251)装SVN服务器 ...

  9. java 通过eclipse编辑器用mysql尝试 连接数据库

    注:本人学的是Oracle,用mysql连接数据库是一次尝试. 一.下载JDBC mysql驱动,导入jar包     我自己下载的是connector-java-6.0.6.jar,如下图所示,JD ...

  10. 小程序 wx.getRecorderManager 录音 to 语音识别

    微信扫小程序码看调用效果(自然语言理解小助手) 欢迎转载,请保留原文链接:http://www.happycxz.com/m/?p=125 这次主要是把我的api更新了一下,支持微信小程序新的录音接口 ...