Я сражался с утечками памяти, и я в настоящее время озадачен этой проблемой. Там загрузчик классов веб-приложений, который должен был собираться с мусором, но это не так (даже после того, как я исправил несколько утечек). Я сбросил кучу с помощью jmap и просмотрел его с помощью jhat, нашел загрузчик классов и проверил ссылки на корневые ссылки.
Если исключить слабые ссылки, список пуст! Как это возможно, поскольку объект, содержащий только слабые ссылки, должен собирать мусор? (Я выполнял GC много раз в jconsole)
Если я включаю слабые ссылки, я получаю список ссылок, все из которых относятся к одному из следующих полей:
- java.lang.reflect.Proxy.loaderToCache
- java.lang.reflect.Proxy.proxyClasses
- java.io.ObjectStreamClass $Caches.localDescs
- java.io.ObjectStreamClass $Caches.reflectors
- java.lang.ref.Finalizer.unfinalized
Я не мог найти никакой причины, почему любая из этих ссылок должна предотвращать сбор мусора загрузчика классов. Это ошибка gc? Специальный недокументированный случай? Ошибка jmap/jhat? Или что?
И самое странное... после того, как время от времени простаивало и время от времени в течение примерно 40 минут, ничего не меняя, он решил разгрузить классы и собрать загрузчик классов.
Примечание:
Если вы заявляете о задержке сбора загрузчиков классов или слабых ссылок, укажите, пожалуйста, обстоятельства, в которых это происходит, и в идеале:
- укажите ссылку на авторитетную статью, которая поддерживает вашу заявку.
- предоставить пример программы, демонстрирующей поведение
Если вы считаете, что поведение зависит от реализации, то, пожалуйста, сосредоточьтесь на том, что происходит в oracle или icedtea jvm, версия 6 или 7 (выберите любой из них и будьте конкретными).
Мне бы очень хотелось разобраться в этом. Я действительно приложил некоторые усилия для воспроизведения проблемы в тестовой программе, и я потерпел неудачу - загрузчик классов был немедленно собран на System.gc() каждый раз, если не было сильной ссылки на него.