最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

深度分析java dump文件

 更新時間:2021年05月18日 09:59:31   作者:華為云開發(fā)者社區(qū)  
java內(nèi)存dump是jvm運行時內(nèi)存的一份快照,利用它可以分析是否存在內(nèi)存浪費,可以檢查內(nèi)存管理是否合理,當(dāng)發(fā)生OOM的時候,可以找出問題的原因。那么dump文件的內(nèi)容是什么樣的呢?

JVM dump

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

獲取JVM dump文件

獲取dump文件的方式分為主動和被動

主動方式:

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

2.利用jcmd,jcmd GC.heap_dump

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

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-heap-dump-capture)

被動方式:

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

dump文件分析

結(jié)構(gòu)示意圖

結(jié)構(gòu)詳解

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

文件頭

由musk, 版本,identifierSize, 時間4部分組成

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

4、time:8個byte,dump文件生成時間

java一個類的成員變量有兩種類型

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

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

例如定義一個類

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

當(dāng)我們在new Person()的時候

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

對象大小的測量:

jdk提供一個測試對象占用內(nèi)存大小的工具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

定義一個執(zhí)行類, 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執(zhí)行

java -javaagent:premain.jar PersonTest

結(jié)果:

person size:[32]B

class size:[504]B

內(nèi)容塊

每個塊都是塊頭和塊體組成

塊頭

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

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

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

3.棧楨,由identifierSize個byte的楨id,identifierSize個byte的方法名id,identifierSize個byte的方法標(biāo)識id,identifierSize個byte的類文件名id,4個byte的類序列,4個byte的行號

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

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

gc root

gc root有4種結(jié)構(gòu),8種類型

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

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

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

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

gc root示意圖

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

系統(tǒng)類,只有classLoader為null的類才是gc root,每個類都是一個gc root
線程棧,線程中方法參數(shù),局部變量都是gc root,每個對象都是一個gc root
系統(tǒng)保留對象,每個對象都是一個gc root

類對象

基本信息

1.identifierSize個byte的類對象id

2.4個byte的棧序列號

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

4.identifierSize個byte的classLoader對象id,

5.identifierSize個byte的Signer對象id,

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

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

8.4個byte的類實例對象大小,

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

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

11.2個byte的成員變量個數(shù),后面是每個成員變量的,identifierSize個byte的變量名id,1個byte的變量類型

說明

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

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

實例對象

1、基本信息:

  • identifierSize個byte的實例對象id
  • 4個byte的棧序列號
  • identifierSize個byte的類id
  • 4個byte的占用字節(jié)數(shù)
  • 實例的變量的值

2、說明:

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

基本類型數(shù)組

基本信息

  • identifierSize個byte的數(shù)組對象id
  • 4個byte的棧序列號
  • 4個byte的數(shù)組長度
  • 1個byte的元素類型
  • 元素的值列表

說明

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

對象數(shù)組

基本信息:

  • identifierSize個byte的數(shù)組對象id
  • 4個byte的棧序列號
  • 4個byte的數(shù)組長度
  • identifierSize個byte的元素類id
  • 元素的值列表

內(nèi)存分配

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

內(nèi)存回收規(guī)則

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

對象回收規(guī)則包括

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

類對象被實例引用,只有當(dāng)一個類的所有實例都被回收了,類才能被回收類

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

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

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工具,執(zhí)行

jhat xxx.dump

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

一般使用方法

瀏覽器打開http:/127.0.0.1:7000

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

點擊頁面的堆內(nèi)存統(tǒng)計

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

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

主要展現(xiàn)該類下面各個實例的大小,以及一些鏈接導(dǎo)航

點擊references summary by type

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

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

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

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

相關(guān)文章

  • java實現(xiàn)在線預(yù)覽--poi實現(xiàn)word、excel、ppt轉(zhuǎn)html的方法

    java實現(xiàn)在線預(yù)覽--poi實現(xiàn)word、excel、ppt轉(zhuǎn)html的方法

    這篇文章主要介紹了java實現(xiàn)在線預(yù)覽--poi實現(xiàn)word、excel、ppt轉(zhuǎn)html的方法,本文需要引入poi的jar包給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2019-09-09
  • IDEA生成可運行jar包(包含第三方j(luò)ar包)流程詳解

    IDEA生成可運行jar包(包含第三方j(luò)ar包)流程詳解

    這篇文章主要介紹了IDEA生成可運行jar包(包含第三方j(luò)ar包)流程詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-11-11
  • 二叉排序樹的實現(xiàn)與基本操作

    二叉排序樹的實現(xiàn)與基本操作

    二叉排序樹又稱二叉查找樹。本文主要對二叉排序樹的實現(xiàn)與基本操作進行詳細(xì)介紹,以下代碼實現(xiàn)了:1、二叉樹的構(gòu)建;2、二叉樹的中、前、后、層序遍歷;3、二叉樹中結(jié)點的最大距離。下面就跟著小編一起來看下吧
    2016-12-12
  • java數(shù)據(jù)結(jié)構(gòu)與算法之插入排序詳解

    java數(shù)據(jù)結(jié)構(gòu)與算法之插入排序詳解

    這篇文章主要介紹了java數(shù)據(jù)結(jié)構(gòu)與算法之插入排序,結(jié)合實例形式分析了java插入排序的概念、分類、原理、實現(xiàn)方法與相關(guān)注意事項,需要的朋友可以參考下
    2017-05-05
  • Java執(zhí)行SQL腳本文件到數(shù)據(jù)庫詳解

    Java執(zhí)行SQL腳本文件到數(shù)據(jù)庫詳解

    這篇文章主要為大家詳細(xì)介紹了Java執(zhí)行SQL腳本文件到數(shù)據(jù)庫的相關(guān)方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • Jenkins自動化打包為war包

    Jenkins自動化打包為war包

    這篇文章主要介紹了Jenkins自動化打包為war包,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • Java數(shù)據(jù)結(jié)構(gòu)之LinkedList從鏈表到實現(xiàn)

    Java數(shù)據(jù)結(jié)構(gòu)之LinkedList從鏈表到實現(xiàn)

    LinkedList是Java中常用的數(shù)據(jù)結(jié)構(gòu)之一,實現(xiàn)了鏈表的特性,支持快速添加、刪除元素,可以用于實現(xiàn)隊列、棧、雙向隊列等數(shù)據(jù)結(jié)構(gòu)。LinkedList的內(nèi)部實現(xiàn)采用了雙向鏈表,其中每個節(jié)點都包含前驅(qū)節(jié)點和后繼節(jié)點的引用,可以直接訪問鏈表的頭尾元素
    2023-04-04
  • SpringCloud turbine監(jiān)控實現(xiàn)過程解析

    SpringCloud turbine監(jiān)控實現(xiàn)過程解析

    這篇文章主要介紹了SpringCloud turbine監(jiān)控實現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-12-12
  • Mybatis 條件查詢 批量增刪改查功能

    Mybatis 條件查詢 批量增刪改查功能

    這篇文章主要介紹了mybatis 腳本處理語句之條件查詢 批量增刪改查功能,需要的的朋友參考下吧
    2017-06-06
  • Java制作證書的工具keytool用法詳解

    Java制作證書的工具keytool用法詳解

    本文主要介紹了Java制作證書的工具keytool用法詳解,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02

最新評論

英吉沙县| 乐亭县| 清流县| 彩票| 家居| 西畴县| 闻喜县| 扎囊县| 治多县| 银川市| 柯坪县| 广河县| 姚安县| 海晏县| 冕宁县| 平果县| 南溪县| 祁阳县| 六盘水市| 西畴县| 界首市| 望江县| 南雄市| 博兴县| 建湖县| 北碚区| 曲阜市| 浦城县| 巴林右旗| 周至县| 濮阳县| 兴仁县| 漳平市| 南岸区| 青铜峡市| 靖江市| 云林县| 交城县| 开远市| 肃北| 武城县|