у меня в одном из проектов есть реализация сложного механизма класс-лоадеров, все работает замечательно. Главное правильно сделать все. Т.е. проблема решается. К примеру, в Rhino (имплементация javascript на java) была указанная вами проблема, однако, залез внутрь переписал одно из мест, работает отлично.
при каждом вызове скрипта Rhino генерит один из классов который отвечает за работу оператора print, причем этот класс постоянно имеет новое имя. При периодическом вызове скрипта каждую секунду, сервак падал с ошибкой OutOfMemoryError, после рефактиринга работает многие сутки напролет.
я думаю, размер особого значения не имеет, при длительной работе при наличии утечки памяти даже самый маленький класс приведет к OOME, а при правильной реализации и большие классы отрабатывают отлично.
Интересно было бы почтить как автор решает проблему полной перегрузки ранее загруженных классов…
Сам не сталкивался, однако знаю от коллег, что многократный ридиплой в аппсервер на ней так же приводит к ошибке. Даже если там нет прямого эквивалента сановского Perm, что-то приводит к аналогичному сбою управления кучей (или где там у них лежат классы).
Считаю нужным пояснить, что в первом комментарии я скорее имел в виду, что JVM склонны давать такую ошибку не смотря на принимаемые меры в виде аккуратного кодирования, правильной работы с загрузчиками и настройки машины свичами и т.п. Как показывает практика, эти меры имеют разный эффект для разных машин, и проблема скорее лежит в том, что поведение загрузчиков не специфицировано должным образом. Поэтому динамическая подгрузка классов может быть компромиссом между надежностью системы и сложностью развертывания, и в некоторых случаях неизбежна.
Нет. В Hotspot объем class metadata ограничен размером Permanent Generation (по умолчанию 64Mb). В JRockit объем class metadata не ограничен, т.е. классы будут загружаться, пока есть свободная физическая и/или виртуальная память. Таким образом, JRockit лишь откладывает проявление утечек памяти, но не избавляет от них насовсем.
на практике, к сожалению, часто бывает OutOfMemoryError: PermGen space
Только в случае утечки памяти. Но на практике, тут Вы правы, утечки памяти бывают часто, даже у опытных Java программистов. Тем не менее, при выгрузке классов Hotspot вычищает из PermGen ВСЕ, что к ним относится, т.е. приложение с правильной организацией динамической загрузки может работать сколь угодно долго.
P.S. Кстати, хорошая новость: скоро PermGen исчезнет из Hotspot'а насовсем.
Не очень понятна семантика Module.unload(), а вообще да, пишите продолжение. Не забудьте про зависимости между модулями и грабли в виде ClassCastException. И ссылку на OSGi или что-нибудь подобное.
Эх… помню, как в зеленой юности писал свой загрузчик с собственным кэшем загруженных классов.
Потом почитал спецификацию java машины, и все переделал в несколько строк, примерно как в этой статье =)
Загрузка классов в Java. Практика