• 使用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(一) 源码解析

      

  • 相关阅读:
    RabbitMQ(四)
    RabbitMQ(三)
    RabbitMQ(二)
    定位
    响应式布局
    学习前端的一些心得
    css样式大全
    常用标签
    HTML
    app 被拒绝原因
  • 原文地址:https://www.cnblogs.com/mazhimazhi/p/13413212.html
Copyright © 2020-2023  润新知