где массив сохраняется в памяти в java?

Если у меня есть функция, которую я объявляю в этой функции:

Object arr[] = new Object[20];

Где хранится arr и весь массив? куча? куча? Имеет ли значение, находится ли объявление в какой-то функции или в main()?

и скажем, у меня также есть эти командные строки:

arr[0] = new String("abc");
arr[1] = new List();

где хранятся arr[0] и arr[1]?


person Greg Oks    schedule 10.08.2011    source источник
comment
возможный дубликат массив Java хранится в стеке или куче?   -  person Thomas    schedule 31.08.2015


Ответы (4)


Диаграмма памяти:

Диаграмма памяти

Прямоугольники — это ячейки памяти (где могут храниться двоичные числа).
Стрелки — это ссылки на память (т. е. указатели).

person Nayuki    schedule 10.08.2011
comment
Действительно отличный ответ. - person Sumanth Varada; 21.01.2019

Теоретически стек имеет единственный указатель на место в куче, содержащее сам массив. Сам массив представляет собой просто массив указателей, которые также указывают на места в куче, содержащие объекты, на которые вы ссылаетесь.

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

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

new Object[20]
new String("abc")
new List() // This contains a reference to an initial array, which is also on the heap.

Обратите внимание, что в очень редких случаях new String("abc") предпочтительнее "abc", поскольку строковые литералы все равно будут существовать в памяти пакета, а строки неизменяемы. Нет смысла выделять дополнительную память для точной копии строки, которая уже существует в памяти.

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

person StriplingWarrior    schedule 10.08.2011

В Java каждый раз, когда вы используете ключевое слово new, вы выделяете место в куче для хранения объекта.

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

Так, например:

                                    // This array object is
                                    // stored on the heap.
String[] arr                      = new String[5];
// This reference (arr) is stored
// in a variable on the stack.

В случае массива ссылочных типов, таких как Object[], выделенное пространство представляет собой непрерывный блок, достаточно большой для хранения любого количества ссылок, которое будет храниться в массиве. Любая конкретная ссылка, такая как arr[0], сама будет указывать на другое место в куче, где хранится отдельный объект.

The array, somewhere on the heap:
[a*][b*][  ][  ][  ]

a (elsewhere on the heap):
"abc"

b (yet another heap location):
[A List object]

Единственным исключением являются массивы примитивов, такие как int[]: в этом случае сам массив по-прежнему является непрерывным блоком в куче, но каждая позиция в массиве содержит само фактическое значение, а не ссылку на другую позицию в куче. .

person Dan Tao    schedule 10.08.2011

Массив из n строк

  • Последующий список из n ссылок на объекты в куче
  • n одиночных объектов String со ссылкой на массив в куче
  • n массивов символов в куче

Затем этот массив также имеет ссылку, которая может храниться в стеке или (как поле в классе) в куче.

person Stefan Schubert-Peters    schedule 10.08.2011