>  기사  >  Java  >  Java의 싱글톤 모드 가비지 수집 예제에 대한 자세한 설명

Java의 싱글톤 모드 가비지 수집 예제에 대한 자세한 설명

黄舟
黄舟원래의
2017-08-08 10:25:341552검색

이 글은 주로 싱글톤 모드 가비지 컬렉션 관련 정보를 자세히 소개하며, 이는 특정 참고 가치가 있습니다. 관심 있는 친구들이 참고할 수 있습니다.

토론 제안: 싱글톤 개체를 오랫동안 사용하지 않을 경우 jvm의 가비지 수집 메커니즘에 의해 재활용됩니다.产 먼저 이 질문이 발생한 이유에 대해 말씀드리겠습니다. 저는 작년에 디자인 모델의 선(禪)이라는 책을 읽기 전까지는 쓰레기 재활용이 싱글 모델에 미치는 영향을 생각해 본 적이 없습니다. 책에는 j2ee 애플리케이션에서 jvm 가비지 수집 메커니즘이 오랫동안 사용되지 않은 싱글톤 객체를 가비지로 처리하고 CPU가 유휴 상태일 때 재활용한다고 언급되어 있습니다.
"Java and Patterns"를 포함하여 이전에 읽은 여러 디자인 패턴 책에서는 jvm 가비지 수집 메커니즘이 싱글톤에 미치는 영향에 대해 언급하지 않았습니다. 그리고 작업 과정에서 저는 싱글톤 객체가 재활용되는 경험을 해본 적이 없습니다. 게다가 직장에 있는 많은 선배들이 저에게 경고했습니다. 정적 속성을 너무 많이 선언하지 마십시오. 이러한 정적 속성은 로드된 후에 해제되지 않기 때문입니다. 그러므로 나는 jvm 가비지 수집이 싱글톤 객체를 재활용한다는 진술에 회의적입니다. 점차적으로 저는 인터넷상의 동료들과 기술 직원들 사이에 이 문제에 대해 기본적으로 두 가지 반대 세력이 있다는 것을 알게 되었습니다. 그러면 jvm은 오랫동안 사용되지 않은 싱글톤 객체를 재활용합니까?

이 문제에 대한 저자의 개인적인 의견은 재활용되지 않습니다
.

다음은 내 테스트 코드입니다

class Singleton {
 private byte[] a = new byte[6*1024*1024];
 private static Singleton singleton = new Singleton();
 private Singleton(){}
 
 public static Singleton getInstance(){
 return singleton;
 }
}

class Obj {
 private byte[] a = new byte[3*1024*1024];
}

public class Client{
 public static void main(String[] args) throws Exception{
 Singleton.getInstance();
 while(true){
  new Obj();
 }
 }
}

이 프로그램의 목적은 j2ee 컨테이너를 시뮬레이션하는 것입니다. 먼저 이 싱글톤 클래스는 6M의 메모리를 차지하며 프로그램은 무한대에 들어갑니다. 루프, 지속적으로 객체를 생성하고 jvm이 가비지 수집을 수행하도록 한 다음 가비지 수집 정보를 관찰합니다. 가비지 수집 후에도 메모리가 여전히 6M보다 크면 싱글톤 객체가 가비지 수집에 의해 재활용되지 않음을 의미합니다.

이 프로그램을 실행하는데 사용되는 가상머신은 핫스팟 가상머신으로, 우리가 가장 많이 사용하고 있는 Java에서 공식적으로 제공하는 가상머신입니다. 버전은 jdk1.6.0_12

입니다. 런타임 vm 인수 매개변수는 -verbose :gc -Xms20M -Xmx20M입니다. 이는 jvm이 가비지 수집을 수행할 때마다 메모리 정보가 표시되고 jvm의 메모리가 고정 20M으로 설정됨을 의미합니다.


실행 결과:


……
[Full GC 18566K->6278K(20352K), 0.0101066 secs]
[GC 18567K->18566K(20352K), 0.0001978 secs]
[Full GC 18566K->6278K(20352K), 0.0088229 secs]
……


실행 결과를 보면 항상 6M의 공간이 수집되지 않은 것을 알 수 있습니다. 따라서 저자는 적어도 핫스팟 가상 머신에서는 가비지 수집이 싱글톤 개체를 재활용하지 않을 것이라고 믿습니다.

나중에 관련 정보를 확인해 보니 핫스팟 가상 머신의 가비지 수집 알고리즘은 루트 검색 알고리즘을 사용합니다. 이 알고리즘의 기본 아이디어는 모든 "라이브" 객체의 경우 결국 스택이나 정적 저장 영역에 남아 있는 참조를 추적해야 한다는 것입니다. 루트(GC Roots)라는 일련의 참조를 시작점으로 사용하고 이러한 루트에서 시작하여 일련의 경로를 검색하여 Java 힙의 개체에 도달할 수 있으면 해당 개체는 "활성"이며 재활용할 수 없습니다. . 루트로 사용할 수 있는 개체는 다음과 같습니다.



 가상 머신 스택에서 참조되는 개체(스택 프레임의 로컬 변수 테이블).

  • 메서드 영역의 클래스 정적 속성이 참조하는 객체입니다.

  • 메서드 영역의 상수가 참조하는 개체입니다.

  • 로컬 메서드 스택에서 JNI가 참조하는 개체입니다.


  • 메소드 영역은 클래스 관련 정보를 저장하는 데 사용되는 JVM의 메모리 영역입니다. 분명히 Java에서 싱글톤 모드로 생성된 객체는 자체 클래스의 정적 속성에 의해 참조되며 이는 두 번째 기사를 준수합니다. 따라서 싱글톤 객체는 JVM에 의해 가비지 수집되지 않습니다.

jvm 힙에 있는 싱글턴 객체는 가비지 수집되지 않지만, 오랫동안 사용하지 않으면 싱글턴 클래스 자체가 수집되나요? jvm에는 메소드 영역에 대한 가비지 수집 메커니즘도 있기 때문입니다. 싱글톤 클래스가 수집되면 힙의 개체는 루트에 대한 경로를 잃고 필연적으로 가비지 수집됩니다. 이에 저자는 메소드 영역에 대한 핫스팟 가상 머신의 가비지 수집 방법을 확인했습니다. jvm 언로드 클래스에 대한 판단 조건은 다음과 같습니다.



이 클래스의 모든 인스턴스가 재활용되었습니다. Java 힙에 존재하지 않습니다. 모든 인스턴스.

  • 이 클래스를 로드한 ClassLoader가 재활용되었습니다.

  • 이 클래스에 해당하는 java.lang.Class 객체는 어디에서도 참조되지 않으며, 리플렉션을 통해 이 클래스의 메소드에 액세스할 수 없습니다.

세 가지 조건이 모두 충족되는 경우에만 jvm은 가비지 수집 중에 클래스를 언로드합니다. 분명히 싱글톤 클래스는 조건 1을 충족하지 않으므로 싱글톤 클래스는 언로드되지 않습니다. 즉, 싱글톤 클래스의 정적 참조가 jvm 힙의 싱글톤 객체를 가리키는 한 루트 검색 알고리즘에 따라 해당 객체가 가비지인지 여부에 따라 싱글톤 클래스와 싱글톤 객체는 가비지 수집되지 않습니다. 수집 여부는 사용 기간은 중요하지 않으며 개체가 "살아있는" 것인지 여부에 따라 다릅니다. 객체가 오랫동안 사용되지 않고 재활용된다면, 수집 알고리즘은 최근에 사용되지 않은 알고리즘 중 가장 긴 것이어야 하며, 일반적으로 운영 체제의 내부 및 외부 메모리 교환에 사용됩니다. 가상 머신 가비지 수집에 사용되는데 너무 안전하지 않습니까? 위 내용은 작성자의 의견입니다.

위 내용은 Java의 싱글톤 모드 가비지 수집 예제에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.