Java-примитивы, объекты, методы и куча (управление памятью и лучшие практики)

Хорошо, поэтому я развиваюсь на Java уже более года и прилагаю усилия, чтобы глубже погрузиться в язык и его лучшие практики.

Итак, вот что я знаю:

  • Java "проходит по типу" - это примитивы, передаваемые копией и ссылкой на объект по копии (ссылки указывают на их объект в куче).

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

  • Память памяти пермского генератора, где хранятся метаданные класса (используется для отражения).

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

Итак, вот что я хотел бы понять:

  • Где статические и статические окончательные примитивы и ссылки живут, что JVM может использовать один экземпляр?

  • Являются ли статические и статические конечные объекты, хранящиеся в куче (я предполагаю, что они перемещены в режим ожидания)?

  • Что считается лучшей практикой в ​​отношении количества статических окончательных ссылок в приложении?

  • Будет ли создание более статических окончательных ссылок уменьшать количество пространства кучи в JVM?

Я читал много разных объяснений об этом (все были разные) и хотел бы, чтобы опытный ветеран на языке Java мог дать хорошее объяснение. Спасибо заранее!

Ответ 1

Южное пространство включает пространство пространства и пространства для выживших.

Где статические и статические окончательные примитивы и ссылки живут, что JVM может использовать один экземпляр?

Не определено, но в Sun/Oracle JVM статические поля живут в специальном объекте для полей класса. У вас есть один экземпляр для каждого загрузчика классов, поэтому статические поля могут иметь несколько экземпляров.

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

В Sun/Oracle Java 7 они есть. Они могут быть в Перми Генри или где-то еще.

Что считается лучшей практикой в ​​отношении количества статических окончательных ссылок в приложении?

Держите их как минимум.

Будет ли создание более статических окончательных ссылок уменьшать количество пространства кучи в JVM?

Если вы можете изменить окончательное поле в статичное конечное поле, это может сэкономить некоторое пространство (если у вас несколько экземпляров). Однако ясность обычно важнее производительности. (И я сделал бы это для ясности)

BTW: Я развиваюсь на Java уже 13 лет.

Таким образом, может быть несколько экземпляров статических полей - изменяет ли JVM каждый экземпляр

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

если изменяется статическое поле (например, static int instanceCount, где instanceCount ++ выполняется для каждой конструкции объекта)?

Нет.

Кроме того, объекты можно перенести в Perm Gen?

Нет. Должны ли некоторые данные, которые не определены в одном месте, могут быть в любом месте в зависимости от реализации и версии.

Является ли пермский генерал частью кучи?

Это часть старого gen = tenured + perm gen.

Young gen = eden + пространство для выживших * 2

Максимальный размер кучи ограничивает общее количество детей и общее количество. У пермского поколения и прямой памяти есть свои пределы. Файлы с отображением памяти выполняются в соответствии с любыми этими ограничениями.

Это верно для параллельного коллектора по умолчанию и параллельной развертки меток.

Коллекционер G1 не разделяет пространства таким же образом.


Ссылки для более подробной информации

http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html

терминология кучи Java: молодые, старые и постоянные поколения?

http://javarevisited.blogspot.com/2011/04/garbage-collection-in-java.html