使用HSDB查看類變量的內存布局(5)


如下的實例來自Hotspot 垃圾回收之oop_iterate(一) 源碼解析,我做了一些微小的改動。

查看如下實例的內存布局:

package com.test;

public class Parent {
	private   Integer     a = 1;
	protected long        b = 2;
	protected final short c = 3;
	public    char        d ='A';
}  

Son類繼承Parent類,如下:

package com.test;

public class Son extends Parent {
	private   Integer     a = 11;
	protected long        b = 12;
	protected final short c = 13;
	public    char        d ='B';
	
	public static void main(String args[]){
		Son s = new Son();
		System.out.println(s.a);
	}
}

連接上HSDB后,在控制台輸入universe命令,查看當前Java進程的堆內存,如下所示:

hsdb> universe
Heap Parameters:
Gen 0:
  eden [0x00000000ff600000,0x00000000ff680030,0x00000000ff8b0000) space capacity = 2818048, 18.606354469476745 used
  from [0x00000000ff8b0000,0x00000000ff8b0000,0x00000000ff900000) space capacity = 327680, 0.0 used
  to [0x00000000ff900000,0x00000000ff900000,0x00000000ff950000) space capacity = 327680, 0.0 usedInvocations: 0
Gen 1: old [0x00000000ff950000,0x00000000ff950000,0x0000000100000000) space capacity = 7012352, 0.0 usedInvocations: 0

接着輸入如下命令搜索對象的起始地址:

scanoops 0x00000000ff600000 0x0000000100000000 com.test.Son

命令scanoops查看指定類型的實例對象,接受兩個必選參數和一個可選參數:必選參數是要掃描的地址范圍,一個是起始地址一個是結束地址;可選參數用於指定要掃描什么類型的實例對象。

得到表示Son實例的instanceOop的內存首地址,如下:

0x00000000ff670190 com/test/Son

使用inspect命令查看這個地址處的oop的全部數據,如下:

hsdb> inspect 0x00000000ff670190
instance of Oop for com/test/Son @ 0x00000000ff670190 @ 0x00000000ff670190 (size = 48)
_mark: 1
_metadata._compressed_klass: InstanceKlass for com/test/Son
a: Oop for java/lang/Integer @ 0x00000000ff62e970 Oop for java/lang/Integer @ 0x00000000ff62e970
b: 2
c: 3
d: 'A'
a: Oop for java/lang/Integer @ 0x00000000ff62ea10 Oop for java/lang/Integer @ 0x00000000ff62ea10
b: 12
c: 13
d: 'B'

使用了指針壓縮,如果不想使用指針壓縮,可以使用如下jdb命令:

jdb -XX:+UseSerialGC -Xmx10m -XX:-UseCompressedOops

另外還可以使用圖形化的方式查看內存布局。單擊HSDB的Tools->Inspector菜單選項,輸入地址即可,如下圖所示。

 

單擊HSDB工具欄的Tools->Class Brower命令,輸入Parent和Son后,便能查看類中所定義的各個字段的偏移量,如下圖所示。

 

不進行指針壓縮,使用如下命令:

jdb -XX:+UseSerialGC -Xmx10m -XX:-UseCompressedOops

使用univers、scanoops與inspector命令查看對象的內存布局,如下:

hsdb> inspect 0x00007f0ae468b198
instance of Oop for com/test/Son @ 0x00007f0ae468b198 @ 0x00007f0ae468b198 (size = 64)
_mark: 1
_metadata._klass: InstanceKlass for com/test/Son
a: Oop for java/lang/Integer @ 0x00007f0ae463d4d8 Oop for java/lang/Integer @ 0x00007f0ae463d4d8
b: 2
c: 3
d: 'A'
a: Oop for java/lang/Integer @ 0x00007f0ae463d5c8 Oop for java/lang/Integer @ 0x00007f0ae463d5c8
b: 12
c: 13
d: 'B'

使用圖形化的方式查看內存布局,如下圖所示。

 查看類中所定義的各個字段的偏移量,如下圖所示。

 

除了使用HotSpot虛擬機命令、HSDB外,還可以使用JOL等來查看字段的內存布局,使用比較簡單,這里不在介紹。

相關文章的鏈接如下:

1、在Ubuntu 16.04上編譯OpenJDK8的源代碼 

2、調試HotSpot源代碼

3、HotSpot項目結構 

4、HotSpot的啟動過程 

5、HotSpot二分模型(1)

6、HotSpot的類模型(2)  

7、HotSpot的類模型(3) 

8、HotSpot的類模型(4)

9、HotSpot的對象模型(5)  

10、HotSpot的對象模型(6) 

11、操作句柄Handle(7)

12、句柄Handle的釋放(8)

13、類加載器 

14、類的雙親委派機制 

15、核心類的預裝載

16、Java主類的裝載  

17、觸發類的裝載  

18、類文件介紹 

19、文件流 

20、解析Class文件 

21、常量池解析(1) 

22、常量池解析(2)

23、字段解析(1)

24、字段解析之偽共享(2) 

25、字段解析(3)  

26、字段解析之OopMapBlock(4)

作者持續維護的個人博客classloading.com

關注公眾號,有HotSpot源碼剖析系列文章!

 

參考文章:

(1)終於我用JOL打破了你對java對象的所有想象 

(2)Hotspot 垃圾回收之oop_iterate(一) 源碼解析

 

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM