java.lang.instrument.Instrumentation未给出预期结果

java.lang.instrument.Instrumentation未给出预期结果,java,memory,Java,Memory,我使用java.lang.instrument包获取java对象的内存大小(可以嵌套) 我使用下面的方法获取对象大小: import java.lang.instrument.Instrumentation; public class ObjectSizeFetcher { private static Instrumentation instrumentation; public static void premain(String args, Instrumentatio

我使用java.lang.instrument包获取java对象的内存大小(可以嵌套)

我使用下面的方法获取对象大小:

import java.lang.instrument.Instrumentation;

public class ObjectSizeFetcher {
    private static Instrumentation instrumentation;

    public static void premain(String args, Instrumentation inst) {
        instrumentation = inst;
    }

    public static long getObjectSize(Object o) {
        return instrumentation.getObjectSize(o);
    }
}
我的Person类具有以下字段:

private String name ; 

private int age;

private Addresses addresses [] ; 
现在需要以下人员对象的大小:

    Person person = new Person();
    person.setName("aa");
    person.setAge(11);

    Addresses addresses [] = new Addresses[2000];

    for(int i = 0 ; i < 1000 ; i ++){
        addresses[i] = new Addresses();

        addresses[i].setAddress1("dadadadafasfasf"+i);
        addresses[i].setAddress2("dadadadafasfasfdasdsadsd"+i);
    }

    person.setAddresses(addresses);
    System.out.println("size : " + ObjectSizeFetcher.getObjectSize(person));
Person-Person=新的Person();
个人名称(“aa”);
人。设置(11);
地址[]=新地址[2000];
对于(int i=0;i<1000;i++){
地址[i]=新地址();
地址[i].setAddress1(“dadadadafasfasf”+i);
地址[i].setAddress2(“dadadadafasfasfdasdsadsd”+i);
}
个人地址(地址);
System.out.println(“大小:“+ObjectSizeFetcher.getObjectSize(person));
现在,在执行此操作之后,我得到的输出为:

尺码:24

问题是,如果我迭代这个循环10次,1000次,或者100000次,我得到的大小是24

我预计,当person对象具有更多地址时,如果循环次数增加,person对象内存大小应该增加


为什么java.lang.instrument.Instrumentation没有给出正确的结果

简单地说:一个对象由它自己的字段组成。但若这些字段本身就是对象,那个么它们只包含对那个些其他对象的引用。因此,数组是一个对象,只包含对该数组的引用。换句话说,大小不包含对象存在的整个对象树。

数组本身就是对象,您只声明一个数组

Addresses addresses [] = new Addresses[2000]; //the single array instance

for(int i = 0 ; i < 1000 ; i ++){
    addresses[i] = new Addresses();

    addresses[i].setAddress1("dadadadafasfasf"+i);
    addresses[i].setAddress2("dadadadafasfasfdasdsadsd"+i);
}
地址[]=新地址[2000]//单个数组实例
对于(int i=0;i<1000;i++){
地址[i]=新地址();
地址[i].setAddress1(“dadadadafasfasf”+i);
地址[i].setAddress2(“dadadadafasfasfdasdsadsd”+i);
}
并用地址记录填充它。因此,您的arrray指向内存中相同的区域,它仍然是相同的引用。唯一的区别是您正在创建新的
地址
实例,并在声明数组
地址[]
的类之外填充内存。以作进一步解释

前:地址[]--->0x0000f->{}

之后:地址[]--->0x0000f->{address1,address2,…,address1000}


因此,您对
地址[]
的引用保持不变,它始终指向相同的区域。它只是引用,而不是数组本身。

谢谢,如果我需要检查整个对象树的内存大小,是否有任何限制?我不确定是否存在。如果它存在,它应该在探查器包中。但请注意,参考文献可能是循环的,参考文献也可能用于表示关系而不是组合,因此信息很快就会变得混乱。我想有一些答案我同意你的评论。顺便问一下,你能建议如何获得预期的结果吗?