когда классы в банках входят в PermGen

Насколько я понимаю, PermGen (в некотором смысле) хранит код класса в памяти. Часто у нас есть много файлов jar, на которые ссылается наш путь к классам. Когда файл jar включен в путь к классам (скажем, в каталоге lib tomcat), все ли классы всех этих jar-файлов автоматически загружаются в PermGen?

В аналогичном вопросе, когда используется класс файла jar, загружает ли PermGen все классы в этом файле jar или только используемый класс (а затем при необходимости загружает остальные файлы классов)?


person adamSpline    schedule 21.05.2012    source источник


Ответы (4)


Это в некоторой степени зависит от реализации загрузчика классов и JVM - спецификация виртуальной машины Java говорит следующее:

Эта спецификация обеспечивает гибкость реализации в отношении операций связывания (и, из-за рекурсии, загрузки), при условии соблюдения семантики языка программирования [...]

Например, реализация может разрешать каждую символическую ссылку в классе или интерфейсе по отдельности, только когда она используется (ленивое или позднее разрешение), или разрешать их все сразу во время проверки класса (статическое разрешение). Это означает, что в некоторых реализациях процесс разрешения может продолжаться после инициализации класса или интерфейса.

На практике ни одна разумная реализация не должна автоматически загружать все в файле JAR только потому, что загружен один класс в файле, не говоря уже только о том, что он находится в пути к классам.

person Michael Borgwardt    schedule 21.05.2012

PermGen — это деталь реализации HotSpot, и Oracle заявила, что хочет избавиться от нее в будущем [1]. Это не является частью спецификации Java (VM). Только загруженные классы попадают в PermGen. Либо явно через ClassLoader#loadClass, либо неявно через ссылку. Это должны быть только используемые классы (и их зависимости), если только кто-то явно не загружает все классы, например. выполнять рефлексию над ними. Фреймворки вроде Spring избегают этого и вместо этого сканируют байт-код.

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

[1] JRockit не имеет PermGen, а в последних версиях HotSpot внутренний пул строк больше не находится в PermGen.

person Philippe Marschall    schedule 21.05.2012
comment
Стоит отметить, что в PermGen будут загружены только объекты java.lang.Class, некоторые объекты java.lang.String, связанные с именем класса и именами методов, а также статические объекты, на которые ссылается класс. Это не похоже на то, что ваш байт-код загружается туда или что-то в этом роде... - person Christopher Schultz; 22.05.2012

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

person JB Nizet    schedule 21.05.2012

JLS гарантирует что класс инициализируется, когда - и не раньше - он впервые требуется. Однако реализации разрешено выполнять загрузку и связывание раньше.

person Marko Topolnik    schedule 21.05.2012
comment
На самом деле спецификация явно разрешает предварительную загрузку классов. То, что класс должен быть загружен до того, как он будет использован, довольно очевидно. - person Michael Borgwardt; 21.05.2012
comment
А как насчет их инициализации? - person Marko Topolnik; 21.05.2012
comment
Это другое дело. Я не думаю, что инициализация имеет отношение к использованию PermGen, хотя я полагаю, что реализация может отложить загрузку связанных классов до инициализации. - person Michael Borgwardt; 21.05.2012