Во-первых, в чем разница между пространством Perm и пространством Heap (что и как JVM выбирает для использования каждого пространства памяти)?
Во-вторых, что наиболее важно, какое соотношение рекомендуется для стандартного java-приложения типа MVC?
Ответы:
В куче хранятся все объекты, созданные вашей программой Java. За содержимым кучи следит сборщик мусора, который освобождает память из кучи, когда вы прекращаете использование объекта (то есть когда больше нет ссылок на объект.
Это контрастирует со стеком , который хранит примитивные типы, такие как int и chars, и обычно являются локальными переменными и возвращаемыми значениями функций. Это не сборщик мусора.
Завивка пространство относится к специальной части кучи. См. Этот SO-ответ для объяснения: что такое перманентное пространство?
-XX:MaxPermSize=256m
чтобы установить размер постоянного пространства на 256 МБ.
Лично я бы не стал считать PermGen особой частью кучи.
Я бы предпочел рассматривать кучу как область памяти, предназначенную для хранения экземпляров объектов, а PermGen - как область, предназначенную для определений классов хранения. В результате жизненный цикл кучи привязан к приложению, а жизненный цикл PermGen привязан к JVM.
Один из лучших примеров того, почему приложение и его JVM могут иметь разный жизненный цикл, - это контейнер Java EE. На сервере приложений приложения можно развертывать и отменять без перезапуска сервера. Во время отмены развертывания (или повторного развертывания) легко освободить все экземпляры объекта, то есть пространство кучи, но довольно сложно очистить все классы, загруженные этим приложением, из PermGen, поскольку JVM все еще может ссылаться на некоторые из классов.
Один из таких случаев - утечка драйверов . При развертывании приложения драйвер JDBC загружается и регистрируется в DriverManager. Когда это приложение не развернуто, DriverManager продолжает работать и содержит ссылку на драйвер, его исходный загрузчик классов и все, что загружено этим загрузчиком классов. В результате возникает утечка памяти в PermGen, но это не ошибка управления памятью приложения.
Это правда, что JVM, такие как JRocket, вообще не имеют PermGen, все хранится в куче. Только в таком контексте вы можете назвать PermGen «особой частью» кучи. Даже в этом случае мы все равно должны рассматривать PermGen и кучу по-разному, поскольку они имеют совершенно разные цели и имеют очень разные типы утечек памяти.
Обновление : в Oracle JDK 8 PermGen заменен на «Metaspace», и теперь он официально является частью кучи. Нам больше не нужно специально настраивать PermGen.
Вы НЕ можете давать имена выделенной памяти в куче.
Это означает, что int x
(его имя) выделяется в стеке. Вы можете добраться до указателя по его имени, поэтому указатель находится в стеке. Вы не можете добраться до объекта по его имени, потому что у него нет имени. Доступ к (безымянному) объекту должен осуществляться по его указателю.