자바에서 가비지 컬렉션에 대한 질문이 this topic입니다. 그러나 내가 얻은 대답은 또 다른 질문을했습니다.클래스가 Java에서 언제 가비지 수집됩니까?
누군가 가비지 컬렉터도 클래스를 수집 할 수 있다고 언급했습니다. 사실입니까?
그리고 이것이 사실이라면 어떻게 작동합니까?
자바에서 가비지 컬렉션에 대한 질문이 this topic입니다. 그러나 내가 얻은 대답은 또 다른 질문을했습니다.클래스가 Java에서 언제 가비지 수집됩니까?
누군가 가비지 컬렉터도 클래스를 수집 할 수 있다고 언급했습니다. 사실입니까?
그리고 이것이 사실이라면 어떻게 작동합니까?
Java의 클래스는 아무 것도 참조하지 않을 때 가비지 수집 될 수 있습니다. 대부분의 간단한 설정에서는 이러한 일이 발생하지 않지만 상황이 발생할 수 있습니다. 그 클래스의
는 클래스에 도달하고, 따라서 GC 대상이되지 않도록하는 방법에는 여러 가지가 있습니다. 클래스를 나타내는
Class
객체는 클래스가 여전히 연결할 수로드 ClassLoader
가 ClassLoader
에 의해로드것도 그 중 사실이 없을 경우 , ClassLoader
및로드 된 모든 클래스는 GC에 적합합니다.
는 여기에 건설 예제 동작을 설명한다 그 (나쁜 관행이 가득!) : (포장하지!) x
이 디렉토리에 바이트 코드 파일 GCTester.class
을 작성합니다. 그것은의 소스 코드는 다음과 같습니다
in main Creating ClassLoader Loading Class Getting static field Reading static value [email protected] created Got value: [email protected] First gc() call Second gc() call (in main) [email protected] finalized End of main
에서 :
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.lang.reflect.Field;
public class TestMe {
public static void main(String[] args) throws Exception {
System.out.println("in main");
testGetObject();
System.out.println("Second gc() call (in main)");
System.gc();
Thread.sleep(1000);
System.out.println("End of main");
}
public static void testGetObject() throws Exception {
System.out.println("Creating ClassLoader");
ClassLoader cl = new URLClassLoader(new URL[] {new File("./x").toURI().toURL()});
System.out.println("Loading Class");
Class<?> clazz = cl.loadClass("GCTester");
System.out.println("Getting static field");
Field field = clazz.getField("INSTANCE");
System.out.println("Reading static value");
Object object = field.get(null);
System.out.println("Got value: " + object);
System.out.println("First gc() call");
System.gc();
Thread.sleep(1000);
}
}
이 (또는 유사한) 출력을 생성 TestMe
실행 :
public class GCTester {
public static final GCTester INSTANCE=new GCTester();
private GCTester() {
System.out.println(this + " created");
}
public void finalize() {
System.out.println(this + " finalized");
}
}
그런 다음 x
의 상위 디렉토리에서 클래스 TestMe
을 만들 두 번째 줄부터 마지막 줄까지 GCTester
인스턴스가 완료됨을 알 수 있습니다. 이는 클래스 (및 ClassLoader
)는 가비지 수집 대상입니다.
@ Joachim Sauer : * finalize() *가 호출된다는 사실 만이 입증됩니다. 이 경우 개체가 "도달 할 수없는"상태로 이동하고 GCed가 아닌 것입니다. GC는 의지에 따라 자유롭게 수집 할 수 있습니다. 즉, finalize가 호출되었다고해서 해당 객체가 GCed되었음을 의미하지는 않습니다. GCed되었는지 추적하고 싶다면 PhantomReference를 ReferenceQueue에 놓고 그 큐에서 폴링해야합니다. 그리고 어쨌든, 객체가 실제로 GCed되었음을 증명할지라도, 이것은 클래스와 클래스 로더 (예제에서) 만 GC에 적합하고 자동으로 GCed되지는 않습니다. – SyntaxT3rr0r
@Wizard : 사실, "GC에 적합하다"고 말했어 야합니다. –
@ JoachimSauer, 당신은 'Class'가 GC에 적합하지 못하게하는 4 가지 조건 (4 점)을 명시했습니다. 이제 4 가지 장애물을 해결 했더라도 시스템이 '클래스'를 수집하지 못할 가능성이 있습니까? 기본적으로 JLS는 JVM *이 참조되지 않은'Class'를 릴리즈해야한다고 말하고 있습니까? 아니면 JVM *이 ** 반드시 ** 참조되지 않은'Class'를 릴리스해야한다고 말하는 것입니까? – Pacerier
이 주제가 도움이 될 것입니다 : http://stackoverflow.com/questions/453023/are-static-fields-open-for-garbage-collection –
"Java 클래스 로더가 언제 어떻게 표시됩니까?" 쓰레기 수거를 위해? " http://stackoverflow.com/questions/2344964/when-and-how-is-a-java-classloader-marked-for-garbage-collection – ewernli