日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

聊聊高并发(四)Java对象的表示模型和运行时内存表示

發(fā)布時間:2024/1/17 java 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 聊聊高并发(四)Java对象的表示模型和运行时内存表示 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

在繼續(xù)了解Java內(nèi)存模型之前,最好先理解Java對象的內(nèi)存表示。在網(wǎng)上搜了下Java對象內(nèi)存表示,說得都不夠系統(tǒng)和到位。之前看了《Hotspot實戰(zhàn)》一書,對JVM如何表示對象這塊說得挺好,推薦一下。如果不理解JVM運行時的各種內(nèi)存區(qū)域以及Java調(diào)用的過程,那么很難把Java內(nèi)存模型理解到位。這個是一個比較大的主題,以后會陸續(xù)寫一些JVM相關(guān)的。這里單把Java對象的內(nèi)存拿出來聊聊,文中內(nèi)容都基于Hotspot虛擬機。

?

Hotspot主要是用C++寫的,所以它定義的Java對象表示模型也是基于C++實現(xiàn)的。

Java對象的表示模型叫做“OOP-Klass”二分模型,包括兩部分:

1. OOP,即Ordinary Object Point,普通對象指針。說實話這個名稱挺難理解。說白了其實就是表示對象的實例信息

2. Klass,即Java類的C++對等體,用來描述Java類,包含了元數(shù)據(jù)和方法信息

?

一個Java對象就包括兩部分,數(shù)據(jù)和方法,分別對應(yīng)到OOP和Klass。最簡單的理解就是如果讓你自己用Java語言來開發(fā)一套新的語言,你如何來表示這個新的語言的對象呢??隙ㄒ彩穷愃频乃悸?#xff0c;一個模塊是用Java類來實現(xiàn)表示數(shù)據(jù)的部分,一個模塊是用Java類實現(xiàn)表示方法和元數(shù)據(jù)的部分。

?

JVM運行時加載一個Class時,會在JVM內(nèi)部創(chuàng)建一個instanceKlass對象,表示這個類的運行時元數(shù)據(jù)。創(chuàng)建一個這個Class的Java對象時,會在JVM內(nèi)部相應(yīng)的創(chuàng)建一個instanceOop來表示這個Java對象。熟悉JVM的同學(xué)可以明白,instanceKlass對象放在了方法區(qū),instanceOop放在了堆,instanceOop的引用放在了JVM棧。

?

JVM是基于棧來運行的,當一個線程調(diào)用一個對象的方法時,會在它的JVM棧的棧頂創(chuàng)建一個棧幀(Frame)的數(shù)據(jù)結(jié)構(gòu),這個數(shù)據(jù)結(jié)構(gòu)是用來保存方法的局部變量,操作數(shù)棧,動態(tài)連接和方法返回值的。通過參數(shù)傳遞的值和在方法中new出來的對象的引用都保持在局部變量表里面。

Java的方法調(diào)用是值傳遞,不是引用傳遞,原因就在這里,傳遞進來的參數(shù)相當于在局部變量表里面拷貝了一份,實際計算時,操作數(shù)棧操作的是局部變量變量里面的值,而不是外部的變量。

?

在堆中創(chuàng)建的Java對象實際只包含數(shù)據(jù)信息,它包含三部分:

1. 對象頭,也叫Mark Word

2. 元數(shù)據(jù)指針,可以理解為類對象指針,指向方法區(qū)的instanceKlass實例

3. 實例數(shù)據(jù)

如果是數(shù)據(jù)對象的話,還多了一個部分,就是數(shù)組長度。

對象頭主要存儲對象運行時記錄信息,如hashcode, GC分代年齡,鎖狀態(tài)標志,偏向線程ID,偏向時間戳等。對象頭的長度和JVM的字長一致,比如32位JVM的對象頭是32位,64位JVM的對象頭是64位。

這里可以看到,所謂的給一個對象加鎖,其實就是設(shè)置了對象頭某些位。當其他線程看到這個對象的狀態(tài)是加鎖狀態(tài)后,就等待釋放鎖。

?

在方法區(qū)的instanceKlass對象相當于Class加載后創(chuàng)建的運行時對象,它包含了運行時常量池,字段,方法等元數(shù)據(jù),當調(diào)用一個對象的方法時,如上面的圖所示,實際定位到了方法區(qū)的instanceKlass對象的方法元數(shù)據(jù)。

?

下面我們通過一個實例,使用HSDB來看看運行時的instanceKlass和instanceOop到底是什么樣的。在方法區(qū)

?

創(chuàng)建一個Person類,有name, age, sex實例屬性,有一個sayHi方法

?

?
  • package main;

  • ?
  • public class Person {

  • ?? ?private String name;

  • ?? ?private int age;

  • ?? ?private boolean sex;

  • ?? ?

  • ?? ?public void sayHi(){

  • ?? ??? ?System.out.println("Say hi from ITer_ZC");

  • ?? ?}

  • ?? ?

  • ?? ?public static void main(String[] args){

  • ?? ??? ?Person p = new Person();

  • ?? ??? ?p.sayHi();

  • ?? ??? ?

  • ?? ??? ?try {

  • ?? ??? ??? ?Thread.sleep(500000);

  • ?? ??? ?} catch (InterruptedException e) {

  • ?? ??? ??? ?e.printStackTrace();

  • ?? ??? ?}

  • ?? ?}

  • }

  • ?

  • HSDB是一款內(nèi)置與SA的GUI調(diào)試工具,集成了各種JVM監(jiān)控工具,可以用來深入分析JVM內(nèi)部狀態(tài)。

    ?

    啟動HSDB:

    ?

    java -cp ${JAVA_HOME}/lib/sa-jdi.jar sun.jvm.hotspot.HSDB


    運行Person,使用JPS查看進程ID

    ?

    ?

    使用HSDB attach Person進程

    ?

    Attach成功后看到21461進程里的各個子進程

    ?

    在Class Browser里面找到Person對應(yīng)的instanceKlass的運行時實例

    ?

    在inspector里面查看0x000000077fc82328這個對象實例,我們可以看到instanceKlass的字段,方法,運行時常量池,父類,兄弟類等元數(shù)據(jù)信息

    ?

    在Object Histogram里面找到main.Person對象

    ?

    查看main.Person Oop的運行時實例

    ?

    _mark就是對象頭,接著是實例數(shù)據(jù)信息。HSDB沒有顯示類對象指針

    總結(jié)

    以上是生活随笔為你收集整理的聊聊高并发(四)Java对象的表示模型和运行时内存表示的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。