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

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

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

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

1 ответов


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

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

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

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

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

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

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

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

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

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

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

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

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

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

да.

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

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

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

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

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

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

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

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

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

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

обновление

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