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对象的时候)和内存回收,这两方 ...
随机推荐
- ubuntu上安装adt时无法在线安装的问题
安装了新的ubuntu系统之后,就得重新布置android开发环境了. 找了网上的教程,一步一步做,到了在eclipse上在线下载adt总是出现 Unable to connect to reposi ...
- Leetcode题解(十二)
33.Search in Rotated Sorted Array 题目 这道题目如果没有其他要求,直接遍历一遍就可以知道答案,但是,题目给出了是排序了数组,但是数组有可能经过了旋转得到,其解题思路仍 ...
- ⑦bootstrap按钮 图片 辅助使用基础案例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- WebService--jax-spring集成
如果使用javax.jws内容编写webservice,则只能通过将程序打成jar包的形式运行,如果要想通过web容器进行发布,则需要使用其他webservice框架.下面介绍jaxws与spring ...
- Asp.Net 为什么需要异步
之前看过别人提出为什么在本是多线程的Asp.Net下需要异步环境的时候,提出在Asp.Net环境下本身就是多线程,每个请求就是由一个专门IIS线程负责(咱不说Core下无IIS的情况).所以以此推论A ...
- 通过geotools读写shp文件
依赖jar包 读取shp public static void main(String[] path) { DbaseFileReader reader = null; try { reader = ...
- js判断对象为空 JSON.stringify(obj)
JSON.stringify(obj) : 用于从一个对象解析出字符串 var c = {}; if(JSON.stringify(obj) == "{}"){ console.l ...
- Maven2的配置文件settings.xml
简介: 概览 当Maven运行过程中的各种配置,例如pom.xml,不想绑定到一个固定的project或者要分配给用户时,我们使用settings.xml中的settings元素来确定这些配置.这包含 ...
- C#操作Excel(读取)
一.使用OleDb,这个法子好像不大好使.容易读错.引用System.Data.OleDb; /**//// <summary> /// 返回Excel数据源 ...
- netty 入门(一)
netty Netty提供异步的.事件驱动的网络应用程序框架和工具,用以快速开发高性能.高可靠性的网络服务器和客户端程序.更确切的讲是一个组件,没有那么复杂. 例子 一 Discard服务器端 我们 ...