国产成人精品18p,天天干成人网,无码专区狠狠躁天天躁,美女脱精光隐私扒开免费观看

深度分析java dump文件

發(fā)布時(shí)間:2021-07-05 18:40 來(lái)源:腳本之家 閱讀:0 作者:華為云開(kāi)發(fā)者社區 欄目: 開(kāi)發(fā)技術(shù)

目錄

      JVM dump

      java內存dump是jvm運行時(shí)內存的一份快照,利用它可以分析是否存在內存浪費,可以檢查內存管理是否合理,當發(fā)生OOM的時(shí)候,可以找出問(wèn)題的原因。那么dump文件的內容是什么樣的呢?我們一步一步來(lái)

      獲取JVM dump文件

      獲取dump文件的方式分為主動(dòng)和被動(dòng)

      主動(dòng)方式:

      1.利用jmap,也是最常用的方式:jmap -dump:[live],format=b,file=

      2.利用jcmd,jcmd GC.heap_dump

      3.使用VisualVM,可以界面操作進(jìn)行dump內存

      4.通過(guò)JMX的方式

      MBeanServer server = ManagementFactory.getPlatformMBeanServer();
      HotSpotDiagnosticMXBean mxBean = ManagementFactory.newPlatformMXBeanProxy(server, "com.sun.management:type=HotSpotDiagnostic", HotSpotDiagnosticMXBean.class);
      mxBean.dumpHeap(filePath, live);

      參考()

      被動(dòng)方式:

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

      dump文件分析

      結構示意圖

      結構詳解

      dump文件是堆內存的映射,由文件頭和一系列內容塊組成

      文件頭

      由musk, 版本,identifierSize, 時(shí)間4部分組成

      1、musk:4個(gè)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個(gè)byte數字,值為4或者8,表示一個(gè)引用所占用的byte數

      4、time:8個(gè)byte,dump文件生成時(shí)間

      java一個(gè)類(lèi)的成員變量有兩種類(lèi)型

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

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

      例如定義一個(gè)類(lèi)

      public class Person {
       private int age;//4個(gè)byte
       private String name;//identifierSize個(gè)byte
       private double weight;//8個(gè)byte
      }

      當我們在new Person()的時(shí)候

      它就需要申請一個(gè)空間,空間大小為 對象頭大小+4+identifierSize+8個(gè)byte

      對象大小的測量:

      jdk提供一個(gè)測試對象占用內存大小的工具Instrumentation,但是Instrumentation沒(méi)法直接引用到,需要通過(guò)agent來(lái)引用到
      定義一個(gè)Premain類(lèi), 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;
          }
      }

      編寫(xiě)一個(gè)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

      定義一個(gè)執行類(lèi), 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

      內容塊

      每個(gè)塊都是塊頭和塊體組成

      塊頭

      塊頭由1個(gè)byte的塊類(lèi)型,4個(gè)byte的時(shí)間time,4個(gè)byte的長(cháng)度表示此內容塊占用byte數
      type類(lèi)型一般有5種,字符串,類(lèi),棧楨,棧,及dump塊

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

      2.類(lèi),由4個(gè)byte的類(lèi)序列(在棧楨中使用),identifierSize個(gè)byte的類(lèi)id(解析類(lèi)的時(shí)候用到),4個(gè)byte的序列id(暫未使用),identifierSize個(gè)byte的類(lèi)名id

      3.棧楨,由identifierSize個(gè)byte的楨id,identifierSize個(gè)byte的方法名id,identifierSize個(gè)byte的方法標識id,identifierSize個(gè)byte的類(lèi)文件名id,4個(gè)byte的類(lèi)序列,4個(gè)byte的行號

      4.棧,由4個(gè)byte的棧序號,4個(gè)byte的線(xiàn)程序號,4個(gè)byte的楨數量,后面就是若干個(gè)identifierSize個(gè)byte的楨id

      5.dump塊就是所有對象的內容了,每個(gè)對象由1個(gè)byte的子類(lèi)型,和對象內容結成,子類(lèi)型有6種,gc root, 線(xiàn)程對象,類(lèi),對象,基本類(lèi)型數組,對象數組

      gc root

      gc root有4種結構,8種類(lèi)型

      1,identifierSize個(gè)byte的對象id,類(lèi)型有SYSTEM_CLASS,BUSY_MONITOR, 及未UNKNOWN

      2.identifierSize個(gè)byte的對象id,4個(gè)byte的線(xiàn)程序列號,類(lèi)型有NATIVE_STACK,THREAD_BLOCK

      3.identifierSize個(gè)byte的對象id,4個(gè)byte的線(xiàn)程序列號,4個(gè)byte的棧楨深度,類(lèi)型有JAVA_LOCAL,NATIVE_LOCAL

      4.identifierSize個(gè)byte的對象id,identifierSize個(gè)byte的global refId(暫未使用),類(lèi)型有NATIVE_STATIC

      gc root示意圖

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

      系統類(lèi),只有classLoader為null的類(lèi)才是gc root,每個(gè)類(lèi)都是一個(gè)gc root
      線(xiàn)程棧,線(xiàn)程中方法參數,局部變量都是gc root,每個(gè)對象都是一個(gè)gc root
      系統保留對象,每個(gè)對象都是一個(gè)gc root

      類(lèi)對象

      基本信息

      1.identifierSize個(gè)byte的類(lèi)對象id

      2.4個(gè)byte的棧序列號

      3.identifierSize個(gè)byte的父類(lèi)對象id,

      4.identifierSize個(gè)byte的classLoader對象id,

      5.identifierSize個(gè)byte的Signer對象id,

      6.identifierSize個(gè)byte的protection domain對象id,

      7.identifierSize個(gè)byte的保留id1和id2,

      8.4個(gè)byte的類(lèi)實(shí)例對象大小,

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

      10.2個(gè)byte的靜態(tài)變量個(gè)數,后面是每個(gè)靜態(tài)變量的,identifierSize個(gè)byte的變量名id, 1個(gè)byte的變量類(lèi)型,和若干個(gè)byte的內容,內容根據類(lèi)型來(lái)決定(見(jiàn)類(lèi)對象基本信息的第9條)

      11.2個(gè)byte的成員變量個(gè)數,后面是每個(gè)成員變量的,identifierSize個(gè)byte的變量名id,1個(gè)byte的變量類(lèi)型

      說(shuō)明

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

      (2)類(lèi)的靜態(tài)變量的名稱(chēng)類(lèi)型及值是放在類(lèi)對象里面的,成員變量的名稱(chēng)和類(lèi)型也是放在類(lèi)對象里面的,但是實(shí)例的值是放在實(shí)例對象里面的

      實(shí)例對象

      1、基本信息:

      • identifierSize個(gè)byte的實(shí)例對象id
      • 4個(gè)byte的棧序列號
      • identifierSize個(gè)byte的類(lèi)id
      • 4個(gè)byte的占用字節數
      • 實(shí)例的變量的值

      2、說(shuō)明:

      • 實(shí)例的值為實(shí)例對象的成員變量值,順序為當前類(lèi)的變量值,順序為類(lèi)對象基本信息中第11條中的順序,
      • 然后是父類(lèi)的變量值變量的值基本類(lèi)型都有默認值,引用類(lèi)型默認值為0,占用字節數(見(jiàn)類(lèi)對象基本信息的第9條)

      基本類(lèi)型數組

      基本信息

      • identifierSize個(gè)byte的數組對象id
      • 4個(gè)byte的棧序列號
      • 4個(gè)byte的數組長(cháng)度
      • 1個(gè)byte的元素類(lèi)型
      • 元素的值列表

      說(shuō)明

      元素的值(見(jiàn)類(lèi)對象基本信息的第9條)

      對象數組

      基本信息:

      • identifierSize個(gè)byte的數組對象id
      • 4個(gè)byte的棧序列號
      • 4個(gè)byte的數組長(cháng)度
      • identifierSize個(gè)byte的元素類(lèi)id
      • 元素的值列表

      內存分配

      當一個(gè)線(xiàn)程啟動(dòng)的時(shí)候,進(jìn)程會(huì )去系統內存生成一個(gè)線(xiàn)程棧
      每當發(fā)生一次方法調用,就會(huì )向棧中壓入一個(gè)棧楨,當方法調用完之后,棧楨會(huì )退出
      在運行過(guò)程中,如果有對象的new操作的時(shí)候,進(jìn)程會(huì )去堆區申請一塊內存
      關(guān)于運行時(shí)內存的詳細情況,可以查找相關(guān)的資料

      內存回收規則

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

      對象回收規則包括

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

      類(lèi)對象被實(shí)例引用,只有當一個(gè)類(lèi)的所有實(shí)例都被回收了,類(lèi)才能被回收類(lèi)

      對象的父類(lèi),classLoader對象,signer對象, protection domain對象被類(lèi)引用,只有當類(lèi)被回收了,這些才能被回收

      局部變量(線(xiàn)程棧中)的作用域為一個(gè)大括號

      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可以被回收了

      分析工具簡(jiǎn)介

      分析dump文件,我們可以用jdk里面提供的jhat工具,執行

      jhat xxx.dump

      jhat加載解析xxx.dump文件,并開(kāi)啟一個(gè)簡(jiǎn)易的web服務(wù),默認端口為7000,可以通過(guò)瀏覽器查看內存中的一些統計信息

      一般使用方法

      瀏覽器打開(kāi)http:/127.0.0.1:7000

      會(huì )列出一些功能,包括package下面各個(gè)類(lèi)的概覽,及各個(gè)功能導航

      點(diǎn)擊頁(yè)面的堆內存統計

      有一個(gè)表格,對象類(lèi)型,實(shí)例個(gè)數,實(shí)例所占用內存大小,哪種類(lèi)型的對象占用了內存最多一目了然

      點(diǎn)擊其中認為內存消耗太多的類(lèi)名查看類(lèi)詳情

      主要展現該類(lèi)下面各個(gè)實(shí)例的大小,以及一些鏈接導航

      點(diǎn)擊references summary by type

      如果某種類(lèi)型的對象太多,那么有可能是引用它的那個(gè)類(lèi)的對象太多

      基本上一些簡(jiǎn)單頁(yè)面的查詢(xún),結合原代碼,就可以初步定位內存泄漏的地方

      綜上,dump文件結構還是比較簡(jiǎn)單的,這對于分析線(xiàn)程的執行情況非常有用,也是每一個(gè)Java程序員必須掌握的高級技能之一,你學(xué)會(huì )了嗎?

      以上就是深度分析java dump文件的詳細內容,更多關(guān)于java dump文件的資料請關(guān)注腳本之家其它相關(guān)文章!

      免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自互聯(lián)網(wǎng)轉載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權請聯(lián)系QQ:712375056 進(jìn)行舉報,并提供相關(guān)證據,一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容。

      亚洲中文字幕无码AV正片| 欧洲夜晚福利100集| 乳揉みま痴汉电车中文字幕| 欧洲多毛裸体XXXXX| 性色AV无码中文AV有码VR| 日韩精品无码久久久久久|