Я думаю, что Джереми Хейлер находится на правильном пути, поскольку это проблема финализации.По сути, даже если GC знает, что объект недостижим, до того, как объект действительно будет собран, может пройти неопределенное количество времени, поскольку он может быть поставлен в очередь для завершения.Поток финализатора должен дойти до завершения объекта (что может занять некоторое время, в зависимости от того, сколько других объектов нужно завершить и как выглядят их финализаторы), а затем, после того, как объект был завершен, вам понадобится еще один GC, чтобы заново обнаружить, что объект недоступен до того, как он действительно будет собран.
Плюс, в случае ClassLoader на Sun JVM, он, вероятно, размещен непосредственно в PermGen.Таким образом, вам понадобится не один, а два полных цикла PermGen (один, чтобы получить объект в очередь на завершение, а затем второй, чтобы фактически собрать его).Поскольку развертки PermGen стоят дорого, я считаю, что Sun JVM вообще не выполняет их с настройками по умолчанию, и даже с различными настройками GC, все еще довольно неохотно сканировать PermGen (особенно, если не много другого давления памяти).
Если вместо форсирования (эм, я имею в виду, поощрение ) GC, используя System.gc()
, что если вы сделаете что-то вроде:
System.gc();
System.runFinalization();
System.gc();
OfКонечно, даже это не гарантированно работает, но, по крайней мере, выполняет минимально необходимую работу для очистки большого объекта, необходимого для завершения.