使用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查看类变量的内存布局(5) 

单击HSDB工具栏的Tools->Class Brower命令,输入Parent和Son后,便能查看类中所定义的各个字段的偏移量,如下图所示。

使用HSDB查看类变量的内存布局(5)

使用HSDB查看类变量的内存布局(5) 

不进行指针压缩,使用如下命令:

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'

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

使用HSDB查看类变量的内存布局(5)

 查看类中所定义的各个字段的偏移量,如下图所示。

使用HSDB查看类变量的内存布局(5) 

使用HSDB查看类变量的内存布局(5)

除了使用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源码剖析系列文章!

使用HSDB查看类变量的内存布局(5) 

参考文章:

(1)终于我用JOL打破了你对java对象的所有想象 

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

 

 

  

上一篇:类、对象(oop)


下一篇:【c++ oop】面向对象编程学习整理