Я понимаю, что в Котлине (или Java) объект является ссылочным типом. то есть
private var Object1: Obj1? = Obj1()
Здесь var Object1 — это ссылка (8 байт) на экземпляр класса Obj1 (в куче).
Таким образом, если у меня есть такой класс, как:
class SampleClass {
private var IntVal: Int = 0
private var FloatVal: Float = 0F
private var Object1: Obj1? = Obj1 ()
private var Object2: Obj2? = Obj2 ()
}
Где Obj1 и Obj2 — пользовательские классы:
class Obj1 {
private var IntVal1: Int = 0
private var IntVal2: Int = 0
private var IntVal3: Int = 0
}
class Obj2 {
private var FloatVal1: Float = 0F
private var FloatVal2: Float = 0F
private var FloatVal3: Float = 0F
}
Могу ли я сказать, что размер объекта SampleClass будет равен размеру IntVal (Int: 4 байта) + размер FloatVal (float: 4 байта) + размер двух ссылок на объект, т. е. 8*2: 16 байт.
Таким образом, независимо от размера классов obj1 и obj2, размер SampleClass всегда будет фиксированным (32 байта), поскольку он содержит ссылки на объекты obj1 и obj2, а не сами фактические объекты.
Дайте мне знать, правильно ли я понимаю или нет.
Это правда, что экземпляр SampleClass
будет содержать только ссылки на объекты, а не сами объекты. Они независимы от этого экземпляра. Тем не менее, свойства Object1
и Object2
заполняются новыми объектами всякий раз, когда создается новый экземпляр SampleClass
. Таким образом, общий объем потребляемой памяти всегда включает дополнительное пространство, необходимое для одного Obj1
и одного Obj2
экземпляра.
Если вы установите Object1
и Object2
на null
после создания экземпляра SampleClass
, вы удалите только ссылку. Объекты все еще существуют в памяти и занимают память. Вот тут-то и вступает в игру сборщик мусора: он наблюдает за всеми объектами и подсчитывает, сколько ссылок существует для каждого. Если последняя ссылка на объект была удалена, объект будет удален из памяти. Все это происходит автоматически в фоновом режиме, вам не нужно ничего делать, чтобы это работало. Однако когда именно это произойдет, пока неизвестно. Это зависит от внутреннего устройства сборщика мусора.
Таким образом, объекты независимы друг от друга, и каждый объект имеет свой собственный размер. Их можно создавать вместе, но каждый объект имеет свой собственный жизненный цикл, который определяется тем, как часто на него ссылаются, и соответственно очищается, также независимо от других объектов (если, конечно, они не содержат ссылку).
Трудно предсказать, сколько памяти на самом деле потребляет объект. По крайней мере, это будет сумма его ссылок и примитивов, которые он (и все его родительские элементы) содержит, но будут некоторые дополнительные накладные расходы, которые JVM использует для управления объектами. Однако это не так-то просто определить.
На самом деле существуют разные сборщики мусора с разными алгоритмами для JVM. Прошло довольно много времени с тех пор, как я подробно увлекался сборщиками мусора, но подсчет ссылок, похоже, все еще актуален.
Источники в инете обычно говорят, что накладные расходы памяти составляют 16 байт на объект. Конечно, это никоим образом не гарантировано — могло быть больше, могло быть меньше. Кроме того, я считаю, что сборщики мусора обычно не работают, подсчитывая ссылки. Таким образом, они потерпят неудачу с циклическими ссылками. Но это незначительный комментарий за строгость - он ничего не меняет в вашем ответе.