статическое распределение в java-куче, стеке и постоянной генерации


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

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

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

1 101

1 ответ:

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

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

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

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

насколько я знаю, да. (обновление: видите ниже.)

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

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

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

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

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

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

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

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

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

да.

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

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

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

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

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

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

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

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

  • Как правило, одно слово памяти-это все, что требуется для хранения ссылки на объект или массив, а примитивное значение обычно занимает одно или два слова, в зависимости от архитектуры оборудования.

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

обновление

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