Экономия пространства PermGen с помощью нескольких загрузчиков классов

Мы пишем большое приложение с графическим интерфейсом на Scala с большим количеством классов, и нам пришлось увеличить пространство PermGen, чтобы иметь возможность загружать все классы. Само приложение показывает серию экранных действий, каждое из которых загружает свой собственный большой набор классов. В любой момент времени загружается/отображается только одно действие. Пройдя пару мероприятий, мы получили OutOfMemoryError в пространстве PermGen.

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

So:

  1. Я понимаю, что классы, загруженные системой ClassLoader, не могут быть выгружены, так как на них всегда будет ссылаться их загрузчик классов. Это правда?
  2. Если больше нет экземпляров класса, загруженного моим пользовательским загрузчиком классов, и загрузчик классов может быть собран мусором, будут ли его классы выгружены, освобождая место PermGen?
  3. Есть ли какие-либо предостережения относительно (или распространенных ошибок, которые могут предотвратить) выгрузку классов?

person Jean-Philippe Pellet    schedule 14.10.2011    source источник
comment
Насколько велик ваш PermGen?   -  person Amir Afghani    schedule 14.10.2011
comment
128 м слишком мало, 256 м пока работает, но надолго ли?…   -  person Jean-Philippe Pellet    schedule 14.10.2011


Ответы (1)


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

Да, классы могут быть выгружены только в том случае, если используемый загрузчик классов является сборщиком мусора. Это означает, что ссылки на каждый отдельный класс и на сам загрузчик классов должны быть нулевыми.

Насколько велик ваш PermGen? Вы можете просто использовать PermGen с помощью:

-XX:MaxPermGen=256m

в вашей командной строке. Нередко устанавливается значение 512 м. Если вам нужно действительно надежное решение, вам нужно будет использовать собственный загрузчик классов для каждой «активности». Чтобы облегчить отладку, добавьте в командную строку следующий не требующий пояснений аргумент:

-XX:+TraceClassLoading

Это распечатает классы по мере их загрузки в JVM в командную строку.

person Amir Afghani    schedule 14.10.2011
comment
Спасибо за ответ. Похоже, что -XX:+TraceClassloading недоступен в моей версии JRE 1.6.0_26 в Mac OS X; любая замена? - person Jean-Philippe Pellet; 15.10.2011
comment
Хорошо, это работает, спасибо. Я также использую -XX:+TraceClassUnloading сейчас. - person Jean-Philippe Pellet; 15.10.2011