Я видел в сообщении qaru.site/questions/8557562/...
class Test {
String s = "1";
}
...
MyClassLoader cl = new MyClassLoader();
Object obj = cl.loadClass("Test").newInstance();
obj = null;
cl = null;
// now "1" is eligible for GC if no other class or object references it
Это действительно работает?
Единственное, почему для строкового литерала быть GCed, было бы, если бы все классы, ссылающиеся на него, были выгружены. И даже тогда конкретный сборщик мусора должен быть предназначен для удаления интернированных строк, причем не все они.
Для разгружаемого класса он должен быть загружен загрузчиком пользовательского класса, и загрузчик и все объекты и классы, ссылающиеся на класс, должны быть освобождены/выгружены. Это никогда не случается случайно и достаточно сложно, чтобы это произошло специально.
(Вышеприведенный код пытается это сделать, но, как я уже сказал, это трудно сделать нарочно, поэтому я не могу сказать, работает оно или нет.)
(И, как упоминалось в другом месте, способность к классам GC была включена и выключена несколько раз в истории языка и, скорее всего, является параметром запуска на некоторых современных JVM.)
"1"
ни"Test"
, так как они - до версии java 8 - хранятся в постоянном разделе «поколения» памяти. (Oracle JVM) - не важно, хотя.cl
иobj
вnull
не гарантирует, чтоcl
является предметом коллекционирования. JVM разрешено пропускать ненаблюдаемые назначения или переупорядочивать другие операции перед ними.