jvm内存回收诡异现象
在知乎上看到一篇提问,于是做了个实验帮助他解答,这里整理成一篇文章分享一下。
先看代码如下代码:
/**
* 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内存回收诡异现象的更多相关文章
- JVM内存回收机制简述
JVM内存回收机制涉及的知识点太多了,了解越多越迷糊,汗一个,这里仅简单做个笔记,主要参考<深入理解Java虚拟机:JVM高级特性与最佳实践(第二版)> 目前java的jdk默认虚拟机为H ...
- Java基础-JVM内存回收
Sun的JVMGenerationalCollecting(垃圾回收)原理是这样的:把对象分为年青代(Young).年老代(Tenured).持久代(Perm),对不同生命周期的对象使用不同的算法.( ...
- JVM内存回收机制
1. JVM内存回收机制简述 http://www.cnblogs.com/lzrabbit/p/3826738.html
- JVM内存回收机制——哪些内存需要被回收(JVM学习系列2)
上一篇文章中讨论了Java内存运行时的各个区域,其中程序计数器.虚拟机栈.本地方法栈随线程生灭,且创建时需要多少内存,基本上在译期间就决定的了,所以在内存回收时无需特殊的关注.而堆和方法区则不同,首先 ...
- K8S(18)容器环境下资源限制与jvm内存回收
K8S(18)容器环境下资源限制与jvm内存回收 目录 K8S(18)容器环境下资源限制与jvm内存回收 一.k8s中的java资源限制与可能的问题 方案1:通过JVM的Xms和Xmx参数限制 方案2 ...
- JVM内存回收对象及引用分析
自动垃圾回收是Java相较于C++的一个重要的特点,想了解JVM的垃圾回收机制,首先我们要知道垃圾回收是回收什么地方的垃圾,我在我的上一篇博客<JVM内存区域划分>里面有写到JVM里面的内 ...
- JVM内存回收区域+对象存活的判断+引用类型+垃圾回收线程
此文已由作者赵计刚薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 注意:本文主要参考自<深入理解Java虚拟机(第二版)> 说明:查看本文之前,推荐先知道JVM ...
- 第三章 JVM内存回收区域+对象存活的判断+引用类型+垃圾回收线程
注意:本文主要参考自<深入理解Java虚拟机(第二版)> 说明:查看本文之前,推荐先知道JVM内存结构,见<第一章 JVM内存结构> 1.内存回收的区域 堆:这是GC的主要区域 ...
- Java jvm 内存回收机制
http://blog.csdn.net/yaerfeng/article/details/51291903 在Java中,它的内存管理包括两方面:内存分配(创建Java对象的时候)和内存回收,这两方 ...
随机推荐
- 探究Angular依赖注入对象$injector
$injector其实是一个IOC容器,包含了很多我们通过.module()和$provide创建的模块和服务.$injector服务提供了对依赖注入器对象的访问,当然我们也可以调用angular.i ...
- Power Strings(KMP)
Power Strings Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 45008 Accepted: 18794 D ...
- vue小项目---管理系统
在上一篇文章中我们已经学习了vue的基本语法,常用属性,了解了vue的基本使用,现在让我们用vue配合Bootstrap来完成一个小项目. 首先导入Bootstap文件. <link rel=& ...
- Day1作业要求
Day1作业 作业需求 博客 模拟登录 三级菜单 博客地址 杨振伟Day1博客地址 模拟登录 1.程序说明 实现功能如下 用户输入密码,密码验证后登录成功 用户登录成功后提示登录信息 用户输入3次错误 ...
- 关于jQuery.click()函数
最近接手了前同事的项目,关于使用线程控制实现代码热插拔功能! 在线程中,使用了ChatWebSocketHandler,与前台进行实时交互,今天我拿到需求是这样的,结合chatWebSocketHan ...
- Python丨Python 性能分析大全
虽然运行速度慢是 Python 与生俱来的特点,大多数时候我们用 Python 就意味着放弃对性能的追求.但是,就算是用纯 Python 完成同一个任务,老手写出来的代码可能会比菜鸟写的代码块几倍,甚 ...
- 几种常用的ajax 跨域请求
前 言 首先,我们要明白,什么是跨域,为什么要跨域. 由于JS中存在同源策略.当请求不同协议名不同端口号下面的文件时,将会违背同源策略,无法请求成功!需要进行跨域处理! 这篇文章就为大家详细介绍一 ...
- Python+selenium打开网页
东西都安装好了,是不是都迫不及待的想要运行一个程序呢? 不过不幸的是,在正式编程打开网页之前,我们还需要做一件事:下载驱动. 据说,在很久之前的selenium1和2中,驱动是被内嵌在selenium ...
- RestSharp使用总结
RestSharp是一个轻量的,不依赖任何第三方的组件或者类库的Http的组件.RestSharp具有以下的优点: 1.支持.NET 3.5+,Silverlight 4, Windows Pho ...
- Node.js初探之GET方式传输
Node.js初探之GET方式传输 例子:form用GET方法向后台传东西 html文件: <form action="http://localhost:8080/aaa" ...