JVM dump
在朝阳县等地区,都构建了全面的区域性战略布局,加强发展的系统性、市场前瞻性、产品创新能力,以专注、极致的服务理念,为客户提供成都网站设计、做网站 网站设计制作按需网站设计,公司网站建设,企业网站建设,品牌网站设计,全网营销推广,成都外贸网站制作,朝阳县网站建设费用合理。
java内存dump是jvm运行时内存的一份快照,利用它可以分析是否存在内存浪费,可以检查内存管理是否合理,当发生OOM的时候,可以找出问题的原因。那么dump文件的内容是什么样的呢?我们一步一步来
获取JVM dump文件
获取dump文件的方式分为主动和被动
i.主动方式:
1.利用jmap,也是最常用的方式:jmap -dump:[live],format=b,file=
2.利用jcmd,jcmd GC.heap_dump
3.使用VisualVM,可以界面操作进行dump内存
4.通过JMX的方式
- MBeanServer server = ManagementFactory.getPlatformMBeanServer();
- HotSpotDiagnosticMXBean mxBean = ManagementFactory.newPlatformMXBeanProxy(server, "com.sun.management:type=HotSpotDiagnostic", HotSpotDiagnosticMXBean.class);
- mxBean.dumpHeap(filePath, live);
参考(https://www.baeldung.com/java...
ii.被动方式:
被动方式就是我们通常的OOM事件了,通过设置参数-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=
dump文件分析
结构示意图
结构详解
dump文件是堆内存的映射,由文件头和一系列内容块组成
文件头
由musk, 版本,identifierSize, 时间4部分组成
1、musk:4个byte,内容为'J', 'A', 'V', 'A'即JAVA
2、version:若干byte,值有以下三种
- " PROFILE 1.0\0",
- " PROFILE 1.0.1\0",
- " PROFILE 1.0.2\0"
3、identifierSize:4个byte数字,值为4或者8,表示一个引用所占用的byte数
4、time:8个byte,dump文件生成时间
说明:java一个类的成员变量有两种类型
例如定义一个类
- public class Person {
- private int age;//4个byte
- private String name;//identifierSize个byte
- private double weight;//8个byte
- }
当我们在new Person()的时候
它就需要申请一个空间,空间大小为 对象头大小+4+identifierSize+8个byte
对象大小的测量:
jdk提供一个测试对象占用内存大小的工具Instrumentation,但是Instrumentation没法直接引用到,需要通过agent来引用到
定义一个Premain类, javac Premain.java
- //Premain.java
- public class Premain {
- public static java.lang.instrument.Instrumentation inst;
- public static void premain(String args, java.lang.instrument.Instrumentation inst) {
- Premain.inst = inst;
- }
- }
编写一个Manifest文件
- manifest.mf
- Manifest-Version: 1.0
- Premain-Class: Premain
- Can-Redefine-Classes: true
- Can-Retransform-Classes: true
打包
- jar -cmf manifest.mf premain.jar Premain.class
定义一个执行类, javac PersonTest.java
- //PersonTest.java
- public class PersonTest {
- public static void main(String[] args) throws Exception {
- Class clazz = Class.forName("Premain");
- if (clazz != null) {
- Person p = new Person();
- java.lang.instrument.Instrumentation inst = (java.lang.instrument.Instrumentation)clazz.getDeclaredField("inst").get(null);
- System.out.println("person size:[" + inst.getObjectSize(p) + "]B");
- System.out.println("class size:[" + inst.getObjectSize(p.getClass()) + "]B");
- }
- }
- }
带agent执行
- java -javaagent:premain.jar PersonTest
结果:
- person size:[32]B
- class size:[504]B
内容块
每个块都是块头和块体组成
块头
块头由1个byte的块类型,4个byte的时间time,4个byte的长度表示此内容块占用byte数
type类型一般有5种,字符串,类,栈桢,栈,及dump块
gc root
gc root有4种结构,8种类型
gc root示意图
gc root为垃圾收集追溯的源头,每个gc root都指向一个初始对象,无法追溯的对象是要被回收掉的
系统类,只有classLoader为null的类才是gc root,每个类都是一个gc root
线程栈,线程中方法参数,局部变量都是gc root,每个对象都是一个gc root
系统保留对象,每个对象都是一个gc root
类对象
1、基本信息:
10. 2个byte的静态变量个数,后面是每个静态变量的,identifierSize个byte的变量名id, 1个byte的变量类型,和若干个byte的内容,内容根据类型来决定(见类对象基本信息的第9条)
11. 2个byte的成员变量个数,后面是每个成员变量的,identifierSize个byte的变量名id,1个byte的变量类型
2、说明:
(1)类里面的常量很多地方都没有用上,所以常量个数一般为0
(2)类的静态变量的名称类型及值是放在类对象里面的,成员变量的名称和类型也是放在类对象里面的,但是实例的值是放在实例对象里面的
实例对象
1、基本信息:
2、说明:
基本类型数组
1、基本信息:
2、说明:
对象数组
1、基本信息:
内存分配
当一个线程启动的时候,进程会去系统内存生成一个线程栈
每当发生一次方法调用,就会向栈中压入一个栈桢,当方法调用完之后,栈桢会退出
在运行过程中,如果有对象的new操作的时候,进程会去堆区申请一块内存
关于运行时内存的详细情况,可以查找相关的资料
内存回收规则
如果一个对象不能骑过gc root引用可达,那么这个对象就可能要被回收
对象回收规则包括
- public void test(){
- Object a = new Object();//obj 1
- Object b = new Object();//obj 2
- {
- Object c = new Object();//obj 3
- a = null;//obj 1可以被回收了
- }//obj 3可以回收了
- }//obj 2可以被回收了
分析工具简介
分析dump文件,我们可以用jdk里面提供的jhat工具,执行
- jhat xxx.dump
jhat加载解析xxx.dump文件,并开启一个简易的web服务,默认端口为7000,可以通过浏览器查看内存中的一些统计信息
一般使用方法
1、浏览器打开http:/127.0.0.1:7000
会列出一些功能,包括package下面各个类的概览,及各个功能导航
2、点击页面的堆内存统计
有一个表格,对象类型,实例个数,实例所占用内存大小,哪种类型的对象占用了内存最多一目了然
3、点击其中认为内存消耗太多的类名查看类详情
主要展现该类下面各个实例的大小,以及一些链接导航
4、点击references summary by type
如果某种类型的对象太多,那么有可能是引用它的那个类的对象太多
基本上一些简单页面的查询,结合原代码,就可以初步定位内存泄漏的地方
综上,dump文件结构还是比较简单的,这对于分析线程的执行情况非常有用,也是每一个Java程序员必须掌握的高级技能之一,你学会了吗?
网站名称:干货分享丨jvm系列:dump文件深度分析
网页地址:http://www.gawzjz.com/qtweb/news19/195019.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联