不起眼,但是足以让你收获的JVM内存案例
今天的这个案例我觉得应该会让你涨姿势吧,不管你对JVM有多熟悉,看到这篇文章,应该还是会有点小惊讶的,不过我觉得这个案例我分享出来,是想表达不管多么奇怪的现象请一定要追究下去,会让你慢慢变得强大起来,我对奇怪现象一直充满好奇,所以你碰到些奇怪的问题也可以发给我,当然最好是JVM相关的
问题
因为编辑比较麻烦,直接以截图的方式发出来吧
另外附上测试源码:
这个问题描述其实还挺详细的,另外还附上了测试代码,我比较喜欢这种提问题的方式,可以简单模拟出问题来,这样也比较好分析,问题简化是很重要的一步,这样能节省很多时间,有些现象甚至都不用描述太多,很快就能抓住点
分析
简化程序
这个问题说白了,就是说有些int[]对象不知道是哪里来的,于是我拿他的例子跑了跑,好像还真有这么回事,于是我不断简化他的代码,最终发现int[]对象的多少和线程run方法里的最后一个byte数组的创建有一定关系。
初步疑点
我觉得不应该啊,byte数组在内存里明明就是byte数组,和int数组也没半毛钱关系呀,当时突然灵光一闪,这估计是因为jmx通信导致的吧,因为jvisualvm和目标进程通信,传递一些数据也挺正常,因为当时比较忙,于是就回复他了,也许是jmx导致的,要它不要使用visualvm看了,jmx端口也关了,可以通过jmap -histo来确认下。
再次怀疑
今天突然又收到了该同学的邮件了,他也注意到了和那个byte数组有一定关系
同时他还发现个现象,也就是我要他确认的方式,发现jmap -histo执行的时候,int数组还是比较多,但是加了live参数之后,降下去了,降下去这个比较好解释,因为live参数会做一次fgc的动作,把某些死对象给回收掉了
再次分析
我于是拿它的demo又跑了跑,按照下面的步骤进行操作
- 执行jmap -histo,发现int数组比较多
- 再执行jmap -histo:live,发现int数组降下去了
- 继续执行jmap -histo,int数组又多了点
执行到这里,我就开始怀疑jmap了,难道是因为jmap导致的?于是我开始check jmap的实现,包括JDK和JVM里的逻辑,我要找到哪里可能会创建int数组,JDK层面基本可以忽略,因为实在想不到会有啥逻辑可能会有int数组产生,只是发了个命令给JVM进程而已,于是我重点分析JVM层面的实现,当我们使用jmap做了一次dump的时候或者gc发生的时候都会走到下面的逻辑
因为GC或者内存dump,都必须对内存做一个遍历,因此必须先暂停这些Java线程,防止在遍历内存里的对象的时候进行内存分配,但是每个线程分配内存其实都是优先走tlab(每个线程独有的一块在eden里的小内存块)的,为了能快速遍历对象,而不存在不连续的内存,于是JVM会对tlab做一个填充,填充的正好是int数组对象(从上面代码得知),将剩下的没被分配的tlab内存给填满了,因此在系统运行过程中其实可能伴随着很多无用的对象产生,哈哈,看到这里你是不是豁然开朗?
你是否可以解释如下问题了?
- 线程越多,int数组增长越快
- 没有分配byte数组,int数组增长很慢,甚至不增长?
- jmap其实也不是唯一的因素
这个案例还是非常有意思的,上述问题我抛出来给大家,大家可以到下面留言回答上面的问题,如果没人回答或者没有正确的答案,我到时到下面留言补充,看大家的热情度?欢迎大家转发给更多的人。
推荐阅读:
Java多线程——并发测试
不起眼,但是足以让你收获的JVM内存案例的更多相关文章
- 巧解Tomcat中JVM内存溢出问题
你对Tomcat 的JVM内存溢出问题的解决方法是否了解,这里和大家分享一下,相信本文介绍一定会让你有所收获. tomcat 的JVM内存溢出问题的解决 最近在熟悉一个开发了有几年的项目,需要把数据库 ...
- 《深入分析Java Web技术内幕》读书笔记之JVM内存管理
今天看JVM的过程中收获颇丰,但一想到这些学习心得将来可能被遗忘,便一阵恐慌,自觉得以后要开始坚持做读书笔记了. 操作系统层面的内存管理 物理内存是一切内存管理的基础,Java中使用的内存和应用程序的 ...
- JVM内存参数详解以及配置调优
基本概念:PermGen space:全称是Permanent Generation space.就是说是永久保存的区域,用于存放Class和Meta信息,Class在被Load的时候被放入该区域He ...
- 深入理解java虚拟机学习笔记(一)JVM内存模型
上周末搬家后,家里的宽带一直没弄好,跟电信客服反映了N遍了终于约了个师傅明天早上来迁移宽带,可以结束一个多星期没网的痛苦日子了.这段时间也是各种忙,都一个星期没更新博客了,再不写之前那种状态和激情都要 ...
- JVM内存结构解析
月初的时候个人网站到期了,不想再折腾重新建站了,以后还是来第三方博客写文章吧,可以省去很多问题.之前写的文章也不是很多,备份懒得做了,从头开始吧.博文仅仅是用来记录和学习总结,如有错误之处请帮忙指正! ...
- JVM内存模型总结,有各版本JDK对比、有元空间OOM监控案例、有Java版虚拟机,综合实践学习!
作者:小傅哥 博客:https://bugstack.cn Github:https://github.com/fuzhengwei/CodeGuide/wiki 沉淀.分享.成长,让自己和他人都能有 ...
- 浅谈JVM内存分配与垃圾回收
大家好,我是微尘,最近又去翻了周志明老师的<深入理解Java虚拟机>这本书.已经看了很多遍了,每次都感觉似乎看懂了,但没过多久就忘了.这次翻了第三章的垃圾收集器与内存分配策略,感觉有了新的 ...
- Jvm 内存浅析 及 GC个人学习总结
从诞生至今,20多年过去,Java至今仍是使用最为广泛的语言.这仰赖于Java提供的各种技术和特性,让开发人员能优雅的编写高效的程序.今天我们就来说说Java的一项基本但非常重要的技术内存管理 了解C ...
- jvm系列(二):JVM内存结构
JVM内存结构 所有的Java开发人员可能会遇到这样的困惑?我该为堆内存设置多大空间呢?OutOfMemoryError的异常到底涉及到运行时数据的哪块区域?该怎么解决呢?其实如果你经常解决服务器性能 ...
随机推荐
- Response与ServletContext对象
HTTP协议: 请求消息:客户端发送给服务器端的数据 数据格式: 请求行: 格式: 请求方式 请求url 请求协议/版本 请求头:告诉服务器,当前访问的浏览器自身的一些信息 格式: 请求头名称: 请求 ...
- 解决Bootstrap container样式左右内边距15px,导致屏幕不美观
首先上问题:此问题为bootstrap的 container样式导致,该样式默认左右内边距15px为了栅栏效果而设计,具体看源码css样式,如下图,右侧黄色边框边距和30px,实为两个div左浮动,将 ...
- python面试的100题(14)
32.请写出一个函数满足以下条件 该函数的输入是一个仅包含数字的list,输出一个新的list,其中每一个元素要满足以下条件: 1.该元素是偶数 2.该元素在原list中是在偶数的位置(index是偶 ...
- AcWing 1014. 登山
#include<iostream> using namespace std ; ; int f[N],g[N]; int w[N]; int main() { int n; cin> ...
- 浏览器缓存信息(Autocomplete )
Autocomplete HTML Attribute Not Disabled for Password Field 漏洞详细Web系统被识别到支持自动完成功能,这样通过浏览器可以获取到敏感信息. ...
- Xshell5配置ssh免密码登录-公钥与私钥登录linux服务器(xshell如何登陆上阿里云服务器)
原文地址:https://blog.csdn.net/longgeaisisi/article/details/78680180 ssh登录提供两种认证方式:口令(密码)认证方式和密钥认证方式.其中口 ...
- Spring - Spring Boot - Thymeleaf - textual 模式
概述 thymeleaf 的 text 模式简单使用 过程会比较啰嗦, 需要结论的同学, 可以直接到底部去寻找 背景 想尝试做一个简单的 模板工具 目的 自动生成一些简单的 重复文本 思路 尽量简单 ...
- [P3806] 【模板】点分治 - 点分治
辣鸡蒟蒻怎么今天才来敲这个模板题 好像还敲了很久的样子 (大雾) #include <bits/stdc++.h> using namespace std; #define int lon ...
- C语言循环语句工程用法
-循环语句分析 循环语句的基本工作方式 - 通过条件表达式判断是否执行循环体 - 条件表达式循环if语句表达式的原则 do.while.for的区别 - do语句先执行后判断,循环体至少循环一次 - ...
- Mybaits的中的对象映射(包含仅有基本数据类型的属性的和对象类型的属性的)
转:https://blog.csdn.net/cjt20100/article/details/46547617. 1 constructor – 用来将结果反射给一个实例化好的类的构造器 a ...