中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何深度分析jvm中dump文件

發布時間:2021-10-23 17:22:11 來源:億速云 閱讀:159 作者:柒染 欄目:編程語言

這篇文章將為大家詳細講解有關如何深度分析jvm中dump文件,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。

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);

ii.被動方式:

被動方式就是我們通常的OOM事件了,通過設置參數-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=

dump文件分析

結構示意圖

如何深度分析jvm中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一個類的成員變量有兩種類型

  1. 鴻蒙官方戰略合作共建——HarmonyOS技術社區

  2. 基本類型(8種基本類型),它們占用byte數固定不變,每生成一個對象它們就需要給它們賦初始值,分配空間

  3. 是引用類型,表示一個對象,在類中只有一個引用,引用只是一個數值,所占用的空間大小為identifierSize,被引用對象即將在堆中的另一個地方

      例如定義一個類

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塊

  1. 鴻蒙官方戰略合作共建——HarmonyOS技術社區

  2. 字符串,由identifierSize個byte的字符串id,后面是(length-identifierSize)個byte的字符串內容(后續對字符串是直接引用的這里面的id)

  3. 類,由4個byte的類序列(在棧楨中使用),identifierSize個byte的類id(解析類的時候用到),4個byte的序列id(暫未使用),identifierSize個byte的類名id

  4. 棧楨,由identifierSize個byte的楨id,identifierSize個byte的方法名id,identifierSize個byte的方法標識id,identifierSize個byte的類文件名id,4個byte的類序列,4個byte的行號

  5. 棧,由4個byte的棧序號,4個byte的線程序號,4個byte的楨數量,后面就是若干個identifierSize個byte的楨id

  6. dump塊就是所有對象的內容了,每個對象由1個byte的子類型,和對象內容結成,子類型有6種,gc root, 線程對象,類,對象,基本類型數組,對象數組

gc root

gc root有4種結構,8種類型

  1. 鴻蒙官方戰略合作共建——HarmonyOS技術社區

  2. identifierSize個byte的對象id,類型有SYSTEM_CLASS,BUSY_MONITOR, 及未UNKNOWN

  3. identifierSize個byte的對象id,4個byte的線程序列號,類型有NATIVE_STACK,THREAD_BLOCK

  4. identifierSize個byte的對象id,4個byte的線程序列號,4個byte的棧楨深度,類型有JAVA_LOCAL,NATIVE_LOCAL

  5. identifierSize個byte的對象id,identifierSize個byte的global refId(暫未使用),類型有NATIVE_STATIC

gc root示意圖

gc root為垃圾收集追溯的源頭,每個gc root都指向一個初始對象,無法追溯的對象是要被回收掉的

如何深度分析jvm中dump文件

系統類,只有classLoader為null的類才是gc root,每個類都是一個gc root

線程棧,線程中方法參數,局部變量都是gc root,每個對象都是一個gc root

系統保留對象,每個對象都是一個gc root

類對象

1、基本信息:

  1. 鴻蒙官方戰略合作共建——HarmonyOS技術社區

  2. identifierSize個byte的類對象id

  3. 4個byte的棧序列號,

  4. identifierSize個byte的父類對象id,

  5. identifierSize個byte的classLoader對象id,

  6. identifierSize個byte的Signer對象id,

  7. identifierSize個byte的protection domain對象id,

  8. identifierSize個byte的保留id1和id2,

  9. 4個byte的類實例對象大小,

  10. 2個byte的常量個數,后面是每個常量的,2個byte的下標,1個byte的常量類型,和若干個byte的內容,內容根據類型來決定(boolean/byte為1個byte, char/short為2個byte,float/int為4個byte, double/long為8個byte,引用類型為identifierSize個byte)

   10. 2個byte的靜態變量個數,后面是每個靜態變量的,identifierSize個byte的變量名id, 1個byte的變量類型,和若干個byte的內容,內容根據類型來決定(見類對象基本信息的第9條)

    11.  2個byte的成員變量個數,后面是每個成員變量的,identifierSize個byte的變量名id,1個byte的變量類型

2、說明:

(1)類里面的常量很多地方都沒有用上,所以常量個數一般為0

(2)類的靜態變量的名稱類型及值是放在類對象里面的,成員變量的名稱和類型也是放在類對象里面的,但是實例的值是放在實例對象里面的

實例對象

1、基本信息:

  1. 鴻蒙官方戰略合作共建——HarmonyOS技術社區

  2. identifierSize個byte的實例對象id

  3. 4個byte的棧序列號

  4. identifierSize個byte的類id

  5. 4個byte的占用字節數

  6. 實例的變量的值

2、說明:

  1. 鴻蒙官方戰略合作共建——HarmonyOS技術社區

  2. 實例的值為實例對象的成員變量值,順序為當前類的變量值,順序為類對象基本信息中第11條中的順序,然后是父類的變量值

  3. 變量的值基本類型都有默認值,引用類型默認值為0,占用字節數(見類對象基本信息的第9條)

基本類型數組

1、基本信息:

  1. 鴻蒙官方戰略合作共建——HarmonyOS技術社區

  2. identifierSize個byte的數組對象id

  3. 4個byte的棧序列號

  4. 4個byte的數組長度

  5. 1個byte的元素類型

  6. 元素的值列表

2、說明:

  1. 鴻蒙官方戰略合作共建——HarmonyOS技術社區

  2. 元素的值(見類對象基本信息的第9條)

對象數組

1、基本信息:

  1. 鴻蒙官方戰略合作共建——HarmonyOS技術社區

  2. identifierSize個byte的數組對象id

  3. 4個byte的棧序列號

  4. 4個byte的數組長度

  5. identifierSize個byte的元素類id

  6. 元素的值列表

內存分配

如何深度分析jvm中dump文件

當一個線程啟動的時候,進程會去系統內存生成一個線程棧

每當發生一次方法調用,就會向棧中壓入一個棧楨,當方法調用完之后,棧楨會退出

在運行過程中,如果有對象的new操作的時候,進程會去堆區申請一塊內存

關于運行時內存的詳細情況,可以查找相關的資料

內存回收規則

如果一個對象不能騎過gc root引用可達,那么這個對象就可能要被回收

對象回收規則包括

  1. 鴻蒙官方戰略合作共建——HarmonyOS技術社區

  2. 實例屬性被實例引用,只有當實例被回收了實例屬性才能被回收(只針對強引用)

  3. 類對象被實例引用,只有當一個類的所有實例都被回收了,類才能被回收

  4. 類對象的父類,classLoader對象,signer對象, protection domain對象被類引用,只有當類被回收了,這些才能被回收

  5. 局部變量(線程棧中)的作用域為一個大括號 

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

如何深度分析jvm中dump文件

會列出一些功能,包括package下面各個類的概覽,及各個功能導航

2、點擊頁面的堆內存統計

如何深度分析jvm中dump文件

有一個表格,對象類型,實例個數,實例所占用內存大小,哪種類型的對象占用了內存最多一目了然

3、點擊其中認為內存消耗太多的類名查看類詳情

如何深度分析jvm中dump文件

主要展現該類下面各個實例的大小,以及一些鏈接導航

4、點擊references summary by type

如何深度分析jvm中dump文件

如果某種類型的對象太多,那么有可能是引用它的那個類的對象太多

基本上一些簡單頁面的查詢,結合原代碼,就可以初步定位內存泄漏的地方

關于如何深度分析jvm中dump文件就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

甘南县| 雷山县| 北海市| 吕梁市| 师宗县| 揭阳市| 白水县| 丹寨县| 汤阴县| 郯城县| 邵阳市| 潞城市| 新昌县| 邯郸县| 云林县| 塔城市| 茌平县| 介休市| 清水县| 福泉市| 高雄县| 宝山区| 天门市| 青龙| 枣庄市| 南雄市| 万源市| 三都| 长岭县| 梧州市| 麻江县| 富平县| 揭阳市| 龙南县| 崇仁县| 察哈| 嘉黎县| 澄迈县| 永春县| 东丽区| 腾冲县|