статическое распределение в java - куча, стек и постоянная генерация - PullRequest
110 голосов
/ 03 октября 2010

В последнее время я много читал о схемах выделения памяти в Java, и было много сомнений, поскольку я читал из разных источников. Я собрал свои концепции, и я бы попросил пройтись по всем пунктам и прокомментировать их. Я узнал, что распределение памяти зависит от JVM, поэтому я должен сказать заранее, что мой вопрос относится к Sun.

  1. Классы (загружаемые загрузчиками классов) помещаются в специальную область в куче: Permanent Generation
  2. Вся информация, относящаяся к классу, такая как имя класса, массивы объектов, связанные с классом, внутренние объекты, используемые JVM (например, java / lang / Object) и информация об оптимизации, попадает в область постоянного создания.
  3. Все статические переменные-члены снова сохраняются в области постоянной генерации.
  4. Объекты идут в другую кучу: молодое поколение
  5. В каждом классе есть только одна копия каждого метода, будь то метод статический или нестатический. Эта копия помещается в область постоянного поколения. Для нестатических методов все параметры и локальные переменные попадают в стек - и всякий раз, когда происходит конкретный вызов этого метода, мы получаем новый стековый фрейм, связанный с ним. Я не уверен, где хранятся локальные переменные статического метода. Они в куче постоянного поколения? Или просто их ссылка хранится в области постоянного поколения, а фактическая копия находится где-то еще (где?)
  6. Я также не уверен, где хранится возвращаемый тип метода.
  7. Если объектам (в молодом поколении) необходимо использовать статический член (в постоянном поколении), им дается ссылка на статический член &&, им достаточно места в памяти для хранения возвращаемого типа метода, и т.д.

Спасибо, что прошли через это!

1 Ответ

142 голосов
/ 03 октября 2010

Во-первых, как вам должно быть ясно сейчас, очень мало людей, которые могут подтвердить эти ответы из первых рук.Очень немногие люди работали над недавними JVM HotSpot или изучали их до глубины, необходимой, чтобы действительно знать.Большинство людей здесь (включая меня) отвечают на основании того, что они видели написанным в другом месте, или того, что они сделали вывод.Обычно то, что написано здесь или в различных статьях и на веб-страницах, основано на других источниках, которые могут быть или не быть окончательными.Часто это упрощенно, неточно или просто неправильно.

Если вы хотите получить окончательное подтверждение своих ответов, вам действительно нужно скачать исходный код OpenJDK ... и провести собственное исследование , прочитави понимание исходного кода.Задавать вопросы о SO или обходить случайные веб-статьи не является надежной методикой академических исследований.

Сказав, что ...

1) Классы (загружаемые загрузчиками классов) идутв специальной области в куче: постоянное поколение.

AFAIK, да.( Обновление : см. Ниже.)

2) Вся информация, относящаяся к классу, такая как имя класса, массивы объектов, связанные с классом, внутренние объекты, используемые JVM (как java / lang / Object), и информация об оптимизации поступает в область постоянного поколения.

Более или менее, да.Я не уверен, что вы подразумеваете под некоторыми из этих вещей.Я предполагаю, что «внутренние объекты, используемые JVM (например, java / lang / Object)», означают дескрипторы внутренних классов JVM.

3) Все статические переменные-члены хранятся в области постоянной генерацииснова.

Сами переменные да.Эти переменные (как и все переменные Java) будут содержать либо примитивные значения, либо ссылки на объекты.Однако, хотя статические переменные-члены находятся в кадре, который выделяется в куче permgen, объекты / массивы, на которые ссылаются эти переменные, могут быть размещены в любой куче.

4) Объекты попадают в другую кучу: молодое поколение

Не обязательно.Большие объекты могут размещаться непосредственно в постоянном поколении.

5) В каждом классе имеется только одна копия каждого метода, будь то метод статический или нестатический.Эта копия помещается в область Permanent Generation.

Если вы ссылаетесь на код метода, тогда AFAIK yes.Это может быть немного сложнее, хотя.Например, этот код может существовать в байт-коде и / или формах собственного кода в разное время в течение жизни JVM.

... Для нестатических методов все параметры и локальные переменные попадают в стек- и всякий раз, когда происходит конкретный вызов этого метода, мы получаем новый стековый фрейм, связанный с ним.

Да.

... Я не уверен, где хранятся локальные переменные статического метода.Они в куче постоянного поколения?Или просто их ссылка хранится в области Постоянное поколение, а фактическая копия находится где-то еще (где?)

Нет.Они хранятся в стеке, как локальные переменные в нестатических методах.

6) Я также не уверен, где хранится возвращаемый тип метода.

Если вы имеете в виду значение , возвращаемое (не пустой), затем он возвращается либо в стек, либо в машинный регистр.Если он возвращается в стеке, это занимает 1 или два слова, в зависимости от типа возвращаемого значения.

7) Если объектам (в молодом поколении) необходимо использовать статический член (впостоянное поколение), им дается ссылка на статический член &&, им дается достаточно места в памяти для хранения возвращаемого типа метода и т. д.

Это неточно (или, по крайней мере, выне выразить себя ясно).

Если какой-либо метод обращается к статической переменной-члену, он получает либо примитивное значение, либо объект ссылка .Это может быть назначено (существующей) локальной переменной или параметру, назначено (существующему) статическому или нестатическому элементу, назначено (существующему) элементу ранее выделенного массива или просто использовано и отброшено.* Должно быть выделено для хранения либо ссылки или примитивное значения 1073 *

  • Ни в коем случае не новое хранения.

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

UPDATE

Начиная с Java 8, пространство PermGen было заменено на Metaspace.Для получения дополнительной информации, пожалуйста, обратитесь к этим ресурсам:

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