java.lang.instrument.Instrumentation не дает ожидаемого результата - PullRequest
1 голос
/ 11 ноября 2019

Я использую пакет 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 [] ; 

Теперь нужен размер объекта ниже: Object:

    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));

Теперь, после выполнения этого, я получаю вывод:

размер: 24

Проблема в том, что если я повторяю этот цикл 10 раз, или в 1000 раз, или в 100000 раз, я получаю Размер как 24.

Я ожидаю, что объем памяти объекта персонажа должен увеличиться, если число циклов увеличилось, поскольку объект персона имеет больше адресов.

Почему java.lang.instrument.Instrument не дает правильных результатов?

Ответы [ 2 ]

1 голос
/ 11 ноября 2019

Проще говоря: объект состоит из его собственных полей. Но если эти поля сами являются объектами, они состоят просто из ссылки на эти другие объекты. Таким образом, ваш массив является объектом, и в него включена только ссылка на этот массив. Другими словами, размер не содержит всего дерева объектов того, из чего он существует.

0 голосов
/ 11 ноября 2019

Массивы сами являются объектами, и вы объявляете только один массив.

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);
}

и заполняете его адресными записями. Таким образом, ваш массив указывает ту же область в памяти, это все та же ссылка. Единственное отличие состоит в том, что вы создаете новые Addresses экземпляры и заполняете свою память вне класса, в котором объявлен массив addresses[]. Для дальнейшего объяснения:

До: адреса [] ----> 0x0000f -> {}

После: адреса [] ----> 0x0000f -> {адрес1,address2, ..., address1000}

Таким образом, ваша ссылка для addresses[] остается прежней, она продолжает указывать на ту же область. Это только ссылка, а не сам массив.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...