кога класовете в буркани влизат в PermGen

Моето разбиране е, че PermGen (в известен смисъл) държи кода на класа в паметта. Често имаме много jar файлове, препращащи към нашата класова пътека. Когато jar файл е включен в classpath (да речем в lib директорията на tomcat), всички класове на всички тези jar автоматично ли се зареждат в PermGen?

При подобен въпрос, след като се използва клас от jar файл, PermGen зарежда ли всички класове в този jar файл или само класа, който се използва (и след това по-късно зарежда останалите файлове на класа, когато е необходимо)?


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


Отговори (4)


Това зависи до известна степен от внедряването на програмата за зареждане на класове и JVM - Спецификацията на виртуалната машина на Java казва следното:

Тази спецификация позволява гъвкавост на внедряването по отношение на това кога се извършват дейности по свързване (и, поради рекурсия, зареждане), при условие че се спазва семантиката на езика за програмиране Java, [...]

Например, реализация може да избере да разреши всяка символна препратка в клас или интерфейс поотделно, само когато се използва (мързелива или късна резолюция), или да ги разреши всички наведнъж, докато класът се проверява (статична резолюция). Това означава, че процесът на разрешаване може да продължи, в някои реализации, след инициализиране на клас или интерфейс.

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

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
Струва си да се отбележи, че само обекти java.lang.Class, някои от обектите java.lang.String, свързани с името на класа и имената на методите, и статични обекти, посочени от класа, ще бъдат заредени в PermGen. Не е като вашият байт код да се зарежда там или нещо подобно... - 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