가비지 수집을 위해 정적 필드가 열려 있습니까?


95

프로그램 설정에서만 사용되는 가상 유틸리티 클래스가있는 경우 :

class MyUtils {
   private static MyObject myObject = new MyObject();
   /*package*/static boolean doStuff(Params... params) {
       // do stuff with myObject and params...
   }
}

myObject는 더 이상 사용되지 않을 때 가비지 수집됩니까, 아니면 프로그램 수명 동안 계속 유지됩니까?

답변:


112

클래스가로드되는 동안 가비지 수집을 위해 정적 변수를 선택할 수 없습니다. 각각의 클래스 로더 (이 클래스를로드하는 책임이있는)가 쓰레기를 위해 자체적으로 수집 될 때 수집 될 수 있습니다.

JLS 섹션 12.7 클래스 및 인터페이스 언로드를 확인하십시오.

클래스 또는 인터페이스는 정의 된 클래스 로더가 가비지 수집기에 의해 회수 될 수있는 경우에만 언로드 될 수 있습니다. [...] 부트 스트랩 로더에 의해로드 된 클래스 및 인터페이스는 언로드되지 않을 수 있습니다.


@bruno, 링크 당,로드 된 클래스에 정적 멤버가 없더라도 클래스 로더가로드하는 각 클래스에 대한 참조를 보유한다는 의미입니까?
Pacerier

@brunoconde, 사실 그게 사실이라고 생각하지 않습니다. 정확히 어떤 단락이 그것을 언급합니까? ( stackoverflow.com/questions/405364/…에 대한 토론을 계속하십시오. )
Pacerier

클래스 로더가 가비지 콜렉션에 적합 할 때. ?
Rohit Bandil

@RohitBandil-도달 할 수없는 경우.
Stephen C

55

정적 변수는 ClassLoaders에 의해 참조되는 Class 객체에 의해 참조됩니다. ClassLoader가 어떤 식 으로든 Class를 삭제하지 않거나 (가능하다면) ClassLoader 자체가 수집에 적합하게되지 않는 한 (웹앱 언로드를 생각해보세요) 정적 변수 (또는 오히려 그들이 참조하는 객체)는 수집되지 않습니다.


1
Class정적 변수를 포함하지 객체는 클래스 로더에 의해 참조 얻을?
Pacerier 2014-08-23

14

정적 초기화에 임시 개체를 사용하고 폐기하려면 정적 초기화 블록을 사용할 수 있습니다.

class MyUtils {
   static
   {
      MyObject myObject = new MyObject();
      doStuff(myObject, params);
   }

   static boolean doStuff(MyObject myObject, Params... params) {
       // do stuff with myObject and params...
   }
}

정적 이니셜 라이저 블록은 특별한 종류의 정적 메서드이므로 myObject는 지역 변수이며 블록 실행이 완료된 후 가비지 수집 될 수 있습니다.


13

인 myObject는 인 기준 아닌 개체 . 객체는 도달 할 수 없기 때문에 참조가 가리 키지 않으면 자동으로 가비지 수집됩니다.

따라서 정적 참조 "myObject"뒤에있는 객체는 다음과 같이 역 참조하면 가비지 수집 될 수 있습니다.

myObject = null;

이 개체에 대한 다른 참조가 없습니다.

그러나 정적 참조와 변수는 프로그램 수명 동안 유지됩니다.


StackOverflow에 오신 것을 환영합니다! null끝에 개체를 설정하는 static block것은 실행 가능한 옵션입니다. 하지만 제 경우에는 객체의 수명이 정적 블록보다 길어야했습니다. 객체의 사용 종료는 그다지 구체적이지 않았습니다. 따라서 가비지 수집기를 활용하는 것에 대해 묻습니다.
Michael Deardeuff 2014

7

나는 이것이 당신의 질문에 대답 한다고 생각 합니다 -기본적으로 클래스가 특수 클래스 로더에서 나오고 클래스를 언로드하지 않는 한 기본적으로 아닙니다.


0

여기서 핵심은 클래스 인스턴스 즉, 객체의 가비지 컬렉션입니다. ClassLoader 인스턴스는 본질적으로 Object입니다. 따라서 Classloader 객체가 가비지 수집되지 않은 경우 힙에 저장된 참조 (예 : 정적 항목)는 거의 가비지 수집되지 않습니다. 예외는 문자열 풀입니다.

그래서 갑자기 private static MyGiantClass myGiantObject = new MyGiantClass() 내가 어려운 길을 배운 것처럼 두 번 생각 하기로 결정하기 전에 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.