Class.forName вызывает загрузчик классов перешел в штатное поколение? - PullRequest
3 голосов
/ 26 февраля 2012

Я видел Class.forName () вызывает заполнение штатного поколения.Я подозреваю, что то, что JVM делает внутренне, переместит объекты ClassLoader в постоянное создание.Например, следующий код:

public class Test  {
    public static void main(String[] args) throws Exception {
        for (int i=0 ;i<30000;i++) {
            test();
        }
    }
    private static void test() throws Exception {
        MyClassLoader cl = new MyClassLoader();
        Class.forName("java.lang.String", false, cl);
    }
}

public class MyClassLoader extends ClassLoader {}

выведет журнал gc:

[GC [DefNew: 512K-> 64K (576K), 0,0041095 с] 512K-> 344K (1984K), 0,0042064 с]
[GC [DefNew: 576K-> 64K (576K), 0,0032096 с]] 856K-> 682K (1984K), 0,0032937 с]
[GC [DefNew: 575K-> 63K (576K),0,0032085 с] 1194K-> 1021K (1984K), 0,0033686 с]
[ГХ [DefNew: 575K-> 64K (576K), 0,0025146 с]] 1533K-> 1359 К (1984K), 0,0026305 с]
[ГК [DefNew: 576K-> 64K (576K), 0,0025942 с] [Продолжительность: 1634K-> 166K (1664K), 0,0169541 с] 1871K-> 166K (2240K), 0,0197106 с]
[GC [DefNew: 512K-> 64K(576K), 0,0019209 секунд] 678K-> 505K (1984K), 0,0020053 секунд]
[GC [DefNew: 576K-> 63K (576K), 0,0022846 секунд] 1017K-> 844K (1984K), 0,0024271 секунд]
[GC [DefNew: 575K-> 63K (576K), 0,0023358 секунд] 1356K-> 1182K (1984K), 0,0024235 секунды]
[GC [DefNew: 575K-> 64K (576K), 0,0025660 секунд] [Срок владения:1457K-> 166K (1536K), 0,0136841 с] 1694K-> 166K (2112K), 0,0164004 с]

Если изменить Class.forName до loadClass :

private static void test() throws Exception {
    MyClassLoader cl = new MyClassLoader();
    cl.loadClass("java.lang.String");
    //Class.forName("java.lang.String", false, cl);
}

, тогда вывод gc будет:

[GC [DefNew: 512K-> 63K (576K), 0.0028769секунд] 512K-> 138K (1984K), 0,0029627 секунд]
[GC [DefNew: 575K-> 0K (576K), 0,0009856 секунд] 650K-> 138K (1984K), 0,0010711 секунд]
[GC [DefNew: 512K-> 0K (576K), 0,0006255 секунд] 650K-> 138K (1984K), 0,0007062 секунд]
[GC [DefNew: 512K-> 0K (576K), 0,0002065 секунд] 650K-> 138K (1984K),0,0002861 сек.секунд] 650K-> 138K (1984K), 0,0002796 секунд]
[GC [DefNew: 512K-> 0K (576K), 0,0001704 секунды] 650K-> 138K (1984K), 0,0002481 секунд]
[GC [DefNew: 512K-> 0K (576K), 0,0002229 секунд] 650K-> 138K (1984K), 0,0003118 секунд]

Воспроизведено на солнце jdk1.5 и 1.6.Что здесь происходит внутри jvm (класс load и gc)?

Спасибо.

1 Ответ

1 голос
/ 26 февраля 2012

У вас слишком маленькая выборка, чтобы действительно показать определенную причину различий в поведении ГХ. Прежде всего, ваш MyClassLoader на самом деле не должен загружать класс java.lang.String, потому что он уже присутствует в загрузчике загрузочного класса. Ваши объекты ClassLoader (и сами объекты Class) должны переместиться полностью в пространство PermGen, поэтому ваше предположение о том, что они находятся в постоянном поколении, немного подозрительно.

По сути, ваш вопрос «что происходит внутри JVM здесь» слишком общий - простое чтение выходных данных журнала GC на самом деле мало о чем говорит, поскольку даже кажущиеся тривиальными различия в коде могут привести к диким различиям шаблонов GC, особенно маленький тестовый код.

...