Шаги в процессе выделения памяти для объектов Java
Вопрос
Что происходит в памяти, когда класс создает следующий объект?
public class SomeObject{
private String strSomeProperty;
public SomeObject(String strSomeProperty){
this.strSomeProperty = strSomeProperty;
}
public void setSomeProperty(String strSomeProperty){
this.strSomeProperty = strSomeProperty;
}
public String getSomeProperty(){
return this.strSomeProperty;
}
}
В классе SomeClass1
:
SomeObject so1 = new SomeObject("some property value");
В классе SomeClass2
:
SomeObject so2 = new SomeObject("another property value");
Как выделяется память для нового экземпляра объекта и его свойств?
Решение
Давайте пройдемся по нему:
SomeObject so1 = new SomeObject("some property value");
... на самом деле сложнее, чем кажется, потому что вы создаете новую строку. Это может быть проще думать как:
String tmp = new String("some property value");
SomeObject so1 = new SomeObject(tmp);
// Not that you would normally write it in this way.
(Чтобы быть абсолютно точным - они на самом деле не эквивалентны. В оригинале «новая строка» создается во время компиляции и является частью образа .class. Вы можете думать об этом как о хаке производительности.) р>
Итак, сначала JVM выделяет пространство для строки. Обычно вы не знаете или не заботитесь о внутренних элементах реализации String, поэтому просто верьте, что кусок памяти используется для представления «некоторого значения свойства». Кроме того, у вас временно выделена память, содержащая ссылку на строку. Во второй форме он явно называется tmp
; в исходном виде Java обрабатывает его, не называя его.
Затем JVM выделяет пространство для нового SomeObject. Это немного места для внутренней бухгалтерии Java и места для каждого из полей объекта. В этом случае есть только одно поле, strSomeProperty
.
Помните, что strSomeProperty
- это просто ссылка на строку. Пока что он будет инициализирован нулем.
Затем конструктор выполняется. Р>
this.strSomeProperty = strSomeProperty;
Все, что для этого нужно - скопировать ссылку в строку в поле strSomeProperty
.
Наконец, место выделяется для ссылки на объект so1
. Это устанавливается со ссылкой на SomeObject.
so2
работает точно так же.
Другие советы
Определение использования памяти в Java доктором Хайнцем М. Кабуцем дает точный ответ , плюс программа для расчета использования памяти. Соответствующая часть:
<Ол>Класс занимает не менее 8 байтов. Итак, если вы говорите, новый Object (); вы выделите 8 байт в куче. Каждый элемент данных занимает 4 байта, кроме длинных и двойных, которые занимают 8 байтов. Даже если элемент данных является байтом, он все равно займет 4 байта! Кроме того, объем используемой памяти увеличивается в 8-байтовых блоках. Таким образом, если у вас есть класс, который содержит один байт, он будет занимать 8 байт для класса и 8 байт для данных, всего 16 байт (стон!). Массивы немного умнее. Примитивы упаковываются в массивы, поэтому, если у вас есть массив байтов, каждый из них будет занимать один байт (вау!). Использование памяти, конечно, все еще увеличивается в 8-байтовых блоках Ол>
Как отмечали люди в комментариях, строки - это особый случай, потому что они могут быть интернированы. Вы можете рассуждать о том, какое место они занимают одинаково, но имейте в виду, что то, что выглядит как несколько копий одной и той же строки, может фактически указывать на одну и ту же ссылку.
Что нужно запомнить:
<Ол>Ссылка: http://www.javatutorialhub.com/java-stack-heap. HTML р>