java高分局之寻找JVM中的对象

java高分局之寻找JVM中的对象

作为一个java程序员是不是经常有这样的疑问:java对象在jvm中什么地方?java对象在JVM里是什么模样的呢?

本节我们利用HSDB这个工具来分析一下这两个问题。首先我们写一段代码,如下:

public class Main {
    public static void main(String[] args) {
        User user = new User(27,"chujinhui");

        System.out.println("");
    }
}


class User{
    private int age;
    private String name;

    public User(int age,String name){
        this.age = age;
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

我们在第5行,也就是输出那行加入了断点,让代码停止在第5行,以便于我们从内存中寻找创建的User对象。
cmd进入命令行,输入jps,查找当前程序的进程id如下:
java高分局之寻找JVM中的对象_第1张图片

我们看到当前程序的进程id是3048。

命令行继续输入:java -cp .;%JAVA_HOME%/lib/sa-jdi.jar sun.jvm.hotspot.HSDB 启动HSDB工具。

如下图:
java高分局之寻找JVM中的对象_第2张图片
刚打开时显示此进程中的线程信息,我们选中主线程,也就是最后一个,双击就会打开Inspector窗口
,如下图所示:
java高分局之寻找JVM中的对象_第3张图片
我们在文本框中输出内存地址后,下面会显示此内存地址上的数据。那么现在我们就需要找到User对象
的内存地址。

我们打开HSDB的命令行页面:windows 》 console,如下图所示:
java高分局之寻找JVM中的对象_第4张图片
回车后,就会显示hsdb>提示,输入universe命令,回车后会显示堆信息,如下:

hsdb> universe
Heap Parameters:
Gen 0: eden [0x10200000,0x102eb2f8,0x10650000) space capacity = 4521984, 21.30303866621377 used
from [0x10650000,0x10650000,0x106d0000) space capacity = 524288, 0.0 used
to [0x106d0000,0x106d0000,0x10750000) space capacity = 524288, 0.0 usedInvocations: 0

Gen 1: old [0x15750000,0x15750000,0x16200000) space capacity = 11206656, 0.0 usedInvocations: 0

猜想,我们的User对象应该在年轻代中,输入scanoops 0x10200000 0x10650000 User,回车后如下所示:

hsdb> scanoops 0x10200000 0x10650000 User
0x102de618 User

果真,我们在年轻代中,找到了我们的User对象,并且此对象的地址是:0x102de618,
返回Inspector窗口,在文本框中输入此地址后,如下所示:
java高分局之寻找JVM中的对象_第5张图片
我们现在就看到了User对象在内存中的样子,我们可以分作两部分,第一部分我们叫对象头,第二部分叫实例数据。

对象头又包括两个部分,_mark和_metadata_klass。

_mark:记录我们对象运行时的一些状态。比如,hash码,是否加锁等。

_metadata_klass:是当前类信息的指针,此指针有宽窄之分。在32位机器上是32位的,在64位机器上是64位的指针。

所以在64位机器上我们可以通过设置窄化,来节省一些内存。此指针指向的内容包含当前类的一些信息:

比如Class对象、父类、兄弟类、成员变量信息等。

实例数据:保存对象实例的数据,我们看到其中age是27,name是一个指针指向了“chujinhui”这个常量。

O了。

你可能感兴趣的:(jvm,java高分局)