Примитивные типы Java и структура объектов в памяти - PullRequest
0 голосов
/ 10 октября 2018

Когда мы создаем примитивную переменную Java или объект Java, как она представляется / структурируется в памяти?

int A;

// создается ли ссылка на целочисленный тип?
// является ли пространство памяти необходимым для хранения целочисленного типа, выделенного в памяти?

A = 3;

// теперь, когда пространство памяти, необходимое для хранения целочисленного типа, выделено?затем ссылка на это пространство.

int B = 2;
A = B;

// - это A, ссылающийся на ячейку памяти как B?а старая ячейка памяти, на которую ссылался A, является сборкой мусора?
// если да, то изменение A приведет к изменению также B, верно?
// если нет, то передача по значению выполнена.
// была ли изменена ячейка памяти, на которую ссылается A, или была создана новая ячейка памяти, способная содержать int, заполненная значением, на которое ссылается B, а затем на которую ссылается A?

Это та же аналогия, если A был объектом класса?

Ответы [ 3 ]

0 голосов
/ 10 октября 2018

Примитивы в Java попадают в стек, поэтому они хранятся в месте расположения переменной.Имейте в виду, что, хотя String считается неизменным, это не примитив, а класс.

Таким образом, переменные A и B оба содержат значение 2, но не разделяют значение.Заметим, что Java смешно с переменными типа int.Если они достаточно малы, они на самом деле даже не хранятся в стеке, а ссылаются на статическое распределение в памяти (прекомпилятор обрабатывает это).

Теперь для части, если вы назначите экземпляр класса.Тогда все немного меняется.Если вы назначаете экземпляр A, вы назначаете ссылку на A в стеке и выделяете ее в куче.Когда вы назначаете A для B, оба ссылаются на один и тот же экземпляр в куче.Этот экземпляр не будет собираться мусором, пока обе ссылки не выйдут из области видимости.

Если вы переназначите A или B, они больше не будут указывать на один и тот же экземпляр в куче.

0 голосов
/ 10 октября 2018

Каждый тип данных имеет различный объем данных, который выделяется для хранения этого типа данных, и поэтому у нас есть ограничения на то, насколько большим, например, может быть целое число (от -2 147 483 648 до 2 147 483 647, aмаксимум 32 бита).Другие типы данных, такие как числа с плавающей запятой и двойные числа, имеют разные значения, где число с плавающей запятой - это 32-разрядное значение с плавающей запятой, а значение типа double - 64-разрядное значение с плавающей запятой с двойной точностью.Вы измените B, это изменит A, короткий ответ - нет.Что вы делаете, когда определяете переменную A, равную B, вы изменяете значение A на равное B. Другой пример, если у вас есть приведенный ниже код (любой язык OO), что вы делаетесоздает место в памяти со значением ноль (и выделенным пространством 32 бита), и вы создаете вторую новую переменную со значением переменной a, что равно нулю. edit: вторая переменная полностью независима от первой.

int a = 0;
int b = a;

Есть такая вещь, когда одна переменная может быть изменена путем изменения исходного значения, и это называется указателем,Указатель - это специальный маленький инструмент, который хранит информацию о том, где в памяти хранятся данные, иначе называемый адресом памяти.Взгляните на код ниже.

Person* person = new Person();
int* age = person.age;

Здесь я объявляю два указателя, один из которых является ссылкой на объект, для которого создается экземпляр, а другой - ссылкой на поле в этом объекте.,Указатель хранит информацию о том, где данные хранятся в памяти (адрес памяти).Исходя из этого, всякий раз, когда используется указатель, он действует как указатель на этот адрес памяти, к которому мы будем иметь доступ.Из-за этого он не является на самом деле переменной, а действует как листинг в «оглавлении», где вы можете использовать его для поиска фрагмента данных.Поскольку он не хранит данные напрямую, а просто ссылается на хранимые данные, при непосредственном изменении возраста человека с person.age он также обновляет данные в памяти, ноадрес остается прежним и будет отражать указатель.

Что касается вопроса сбора мусора, то в языке, таком как Java или C #, данные собираются только в том случае, если нет больше ссылок на этот фрагментИнформация.Однако в таком языке, как C ++, сборка мусора автоматически не выполняется, и вы должны удалить указатели, созданные с помощью ключевого слова delete .

В любом случае, надеюсь, это поможет!

0 голосов
/ 10 октября 2018

Управление памятью, которое идет в стеке: не в куче, в вашем сценарии может быть изображено следующим образом: enter image description here

Когда вы делаете, A=B, памятьвыделенное для целого числа, на которое ссылается A, становится подходящим для GC.

Теперь, когда вы изменяете любую переменную, вы ссылаетесь на другое место в памяти, соответствующее этому значению, и поскольку оно находится в стеке,это не повлияет на других.

Например, выполнение A = 6 не повлияет на значение B;B по-прежнему сохраняет значение как 2.

И, наконец, это не то же самое, что в случае, если A был объектом класса, поскольку объект переходит в память кучи.

Загляните в эту статью Wiki , я нахожу это довольно объяснительным.

...