Подтвердить что ты не робот

Почему Java использует кучу для распределения памяти?

Я просто прочитал этот оператор в java-книге, в которой объекты в java находятся в куче. Используется ли куча, потому что это лучший способ хранения данных и быстрого извлечения данных?

У меня есть представление о том, что структуры данных являются новичком. Я имею в виду, почему не стек или что-то еще?

4b9b3361

Ответ 1

Проблема с стеком заключается в том, что вы можете удалить только последнюю добавленную вещь. Это хорошо работает для локальных переменных, поскольку они приходят и уходят, когда вы входите и выходите из функций, но не так хорошо для произвольных данных, жизненный цикл которых не соответствует индивидуальным функциям. Куча памяти позволяет вам добавлять и удалять данные по своему усмотрению.

Ответ 2

Куча используется просто vm для выделения и освобождения блоков памяти. Чтобы получить доступ к объектам, вы используете ссылку на блок памяти (эта ссылка находится в стеке). Jvm не разрешает прямой доступ к памяти (например, в C/С++).

Ответ 3

Это артефакт базовой вычислительной модели. Память к операционной системе выглядит как большое, в основном непрерывное пространство, в котором данные могут быть прочитаны и записаны по адресу. Операционная система позволяет процессам захватывать блок памяти (большое смежное пространство, обычно по крайней мере одну страницу пары K), и делать это по своему усмотрению, используя адреса памяти и операции чтения/записи.

Куча java основывается на этом, то есть программисту, он просто выглядит как большой мешок памяти (это, конечно, не так, т.е. сбор мусора обычно перемещает вещи вокруг), к которому он получает "адреса" (ссылки действительно, они на самом деле не являются адресами) для данных (объектов), записанных в это пространство памяти. Это позволяет вам максимально гибко создавать более специализированные структуры данных.

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

Ответ 4

Поскольку Java использует сборщик мусора для восстановления памяти, в отличие от C и С++. В этих языках имеет смысл использовать стек для локальных переменных *. В Java нет понятия о (локальной) переменной, выходящей из области видимости, только она больше не упоминается, что делает ее пригодной для сбора мусора (которая должна произойти когда-то после этой точки).

*, который для ясности не означает, что в C/С++ не было кучи, или что вы не можете использовать семейство malloc/new для распределения переменных для использования исключительно в пределах локального масштаба.

Ответ 5

Почему бы не хранить объекты в стеке? Ну, что происходит с стеком после того, как текущий исполняемый метод прекращает выполнение?

Ответ 6

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

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

Ответ 7

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

Если Java действительно разрешала объекты быть явно в стеке, что произойдет, когда метод вернется? Что произойдет с любыми ссылками на локальный объект, хранящийся в каких-либо не локальных объектах?

  • Разработчики Java могли бы решить, что некоторые ссылки могут быть недействительными, что приведет к поведению undefined, если разыменован. Также как указатель на C/С++. Разработчики Java, похоже, пошли на многое, чтобы избежать поведения undefined.

  • Дизайнеры Java могли указать, что все ссылки на локальный объект стали нулевыми. Найти все эти ссылки будет сложно. И это приведет к тому, что трудно найти ошибки, вызванные ссылками, которые, как предполагалось, не были null, внезапно стали нулевыми. Неизменяемые объекты, содержащие ссылки на объекты, были бы невозможны. Механизм уведомления, устанавливающий ссылки на null, должен работать по потокам. Стоимость всего этого будет намного выше, чем преимущество локального хранилища.

  • Один из разработчиков языка, Джеймс Гослинг, имеет фон Lisp, и это влияние видно в идее, что удаление объектов остается только сборщику мусора, с удалением объекта компилятора или среды выполнения (анализ побега), если это возможно.