Java對象在JVM中長啥樣

前言

Java 是門面向對象的開發語言,那麼咱們本身編寫的 Java 類生成的對象是什麼樣的?它確定保存在虛擬機的內存中,但它以怎樣的結構來保存的呢?帶着疑問往下看看。數組

關於Klass

Java 層的開發可能不太熟悉 Klass,但確定熟悉 class,咱們只要知道 Klass 是 class 在 JVM 中的表示便可,即 Java class 對應 JVM Klass。C++ 中的繼承關係以下:bash

class MetaspaceObj
    class Metadata
        class Klass
複製代碼

Klass 類用來描述 Java 類信息,包括描述類型自身佈局、類名、父類、子類、兄弟類等等。併發

關於oop

按前面 class 對應的方式,那麼對象也應該有 JVM 內部與之相對應的表示吧?沒錯,就是 oop(ordinary object pointer),普通對象指針。它的定義以下:機器學習

typedef class oopDesc*                            oop;
複製代碼

其中 oopDesc 類是全部 oop 的基類。在 JVM 中,不一樣的 oop 用於描述特定類型的對象。好比類對象用 instanceOopDesc,數組用 arrayOopDesc。分佈式

Klass+oop模型

Java 對象在 JVM 中的結構以下,包括 header 和對象內容。以下圖中,左邊的是 instanceOopDesc,即通常的類對象,header 包括了標識和元數據,標識用於存儲運行時記錄信息,包括哈希碼、GC鎖和線程鎖等等。而右邊的爲 arrayOopDesc,即數組對象,header 多了個 length,用於記錄數組長度。oop

這裏寫圖片描述

來個demo

public class Test {

	private String[] flag = { "a", "b", "c" };
	private String name = "test";

	public static void main(String[] args) throws Exception {
		Test test = new Test();
		String _name = "test";
		System.out.println(test.flag);
		System.out.println(_name);
	}
}
複製代碼

對象結構

在上面程序中打個斷點,經過 jps 查出 pid,而後使用下面命令打開 hsdb,根據 pid 鏈接到 JVM。佈局

jhsdb hsdb
複製代碼

這裏寫圖片描述

查看 main 線程的棧內存,咱們主要是要拿到 Test 對象的地址,即0x000000008a105dd0學習

這裏寫圖片描述

接着用 inspector 來查看0x000000008a105dd0地址對應的 oop,看到這個 oop 就是咱們的 Test 類生成的對象結構了,包含了 mark 和 metadata。這裏可能會有個疑問,就是前面不是說數組還有一個 length 來表示數組長度的嗎?但圖中的 flag 數組變量並無看到 length 啊。ui

這裏寫圖片描述

其實數組 oop 並非沒有 length,而是 C++ 並無聲明這個變量,而是經過指針來直接將數組長度保存到對應的內存了,因此這裏是看不到的。經過下面具體的實現代碼就能清楚瞭解到緣由了。是否是咱們就沒辦法看到這個長度值呢?並非,下面繼續看如何來看這個值。this

int length() const {
    return *(int*)(((intptr_t)this) + length_offset_in_bytes());
  }
  
void set_length(int length) {
    *(int*)(((intptr_t)this) + length_offset_in_bytes()) = length;
  }
複製代碼

前面咱們能夠獲得 flag 數組 oop 的地址爲0x000000008a105de8。64位機器上_mark爲8字節,_metadata爲4字節,那麼將地址加12,獲得0x000000008a105df4。而後用 hsdb 命令行的 examine 獲得地址的值,獲得0x8a105e0800000003,其中00000003即是。

hsdb> examine 0x000000008a105df4
0x000000008a105df4: 0x8a105e0800000003
複製代碼

-------------推薦閱讀------------

個人2017文章彙總——機器學習篇

個人2017文章彙總——Java及中間件

個人2017文章彙總——深度學習篇

個人2017文章彙總——JDK源碼篇

個人2017文章彙總——天然語言處理篇

個人2017文章彙總——Java併發篇


跟我交流,向我提問:

這裏寫圖片描述

公衆號的菜單已分爲「讀書總結」、「分佈式」、「機器學習」、「深度學習」、「NLP」、「Java深度」、「Java併發核心」、「JDK源碼」、「Tomcat內核」等,可能有一款適合你的胃口。

爲何寫《Tomcat內核設計剖析》

歡迎關注:

這裏寫圖片描述
相關文章
相關標籤/搜索