Java에서 SoftReference와 WeakReference의 차이점은 무엇입니까?


810

9
SoftReferences는 (실제로가 아니라 토론을 위해) WeakReferences의 유형입니다. 일반적으로 JVM이 메모리가 부족하다고 생각할 때 수집됩니다.
Ajeet Ganga

5
@AjeetGanga, 느슨한 약한 심판은 항상 GC가 실행될 때마다 수집됩니다.
Pacerier 2009 년

답변:


926

Ethan Nicholas의 약한 참조 이해 에서 :

약한 참조

약한 참조 , 간단히 넣어, 메모리에 남아있는 개체를 강제로 강한 것만으로는 충분하지 않습니다 참조입니다. 약한 참조를 사용하면 가비지 수집기의 접근성을 결정하는 기능을 활용할 수 있으므로 직접 할 필요가 없습니다. 다음과 같이 약한 참조를 만듭니다.

WeakReference weakWidget = new WeakReference(widget);

그런 다음 코드의 다른 곳에서 weakWidget.get()실제 Widget객체 를 얻는 데 사용할 수 있습니다 . 물론 약한 참조는 가비지 수집을 방지하기에 충분히 강력하지 않으므로 weakWidget.get()갑자기 위젯을 참조하지 않는 경우 ( 갑자기 위젯에 대한 참조가없는 경우) 가 반환되기 시작할 수 null있습니다.

...

소프트 레퍼런스

소프트 참조는 참조하는 객체를 버릴 이하 열망하는 것을 제외하고, 정확히 약한 참조 같다. WeakReferences다음 가비지 수집주기에서 약하게 도달 할 수있는 개체 (가장 강한 참조 )는 삭제되지만 일반적으로 부드럽게 도달 할 수있는 개체는 잠시 동안 고정됩니다.

SoftReferences와 다르게 동작 할 필요WeakReferences없지만, 실제로 메모리에 충분한 공급이있는 한 소프트 도달 가능한 객체는 일반적으로 유지됩니다. 가비지 수집기가 개체에 접근 가능한 방법 (강력한 개체는 캐시에서 절대 제거 되지 않음 )과 얼마나 나쁜지에 대해 가비지 수집기에 대해 염려 할 수 있기 때문에 이는 위에서 설명한 이미지 캐시와 같은 캐시의 훌륭한 기반 이됩니다. 그들이 소비하는 메모리가 필요합니다.

그리고 Peter Kessler는 다음과 같이 논평했습니다 :

Sun JRE는 SoftReferences를 WeakReferences와 다르게 처리합니다. 사용 가능한 메모리에 압력이 없으면 SoftReference가 참조하는 객체를 유지하려고 시도합니다. "-client"및 "-server"JRE에 대한 정책이 다릅니다. -client JRE는 힙을 확장하지 않고 SoftReference를 지우는 것을 선호하여 풋 프린트를 작게 유지하려고하지만, -server JRE는 명확한 SoftReference 대신 힙을 확장하는 것을 선호하여 성능을 향상시킵니다. 하나의 크기가 모든 것에 맞지는 않습니다.


7
: 포스트는 더 이상 사용할 수, 당신은 뒤로 머신에서 찾을 수 web.archive.org/web/20061130103858/http://weblogs.java.net/blog/...
riccardo.tasso

이번에는 더 이상 아카이브를 사용할 수 없습니다.
user1506104

209

약한 참조는 열심히 수집됩니다. GC가 객체에 약한 도달 가능 (약한 참조를 통해서만 도달 할 수 있음)이 발견되면 해당 객체에 대한 약한 참조가 즉시 지워집니다. 따라서, 클래스에 대한 캐시 된 리플렉션 정보 또는 객체의 래퍼 등과 같이 프로그램이 "강하게 참조 된" "관련 정보"를 유지하는 객체에 대한 참조를 유지하는 데 좋습니다. 연결된 개체가 GC 버전 이후에 유지되는 것은 의미가 없습니다. 약한 참조가 지워지면 코드가 어딘가에서 폴링하는 참조 큐에 대기하고 관련 개체도 삭제됩니다. 즉, 개체에 대한 추가 정보를 유지하지만 해당 개체가 사라지면 해당 정보가 필요하지 않습니다. 사실은, 특정 상황에서는 WeakReference를 서브 클래 싱하고 WeakReference 서브 클래스의 필드에 객체에 대한 관련 추가 정보를 유지할 수도 있습니다. WeakReference의 또 다른 일반적인 사용은 표준 인스턴스를 유지하기 위해 맵과 함께 사용하는 것입니다.

반면에 SoftReferences는 GC가 일반적으로 삭제를 지연시키기 때문에 재생 가능한 외부 리소스를 캐싱하는 데 좋습니다. OutOfMemoryError가 발생하기 전에 모든 SoftReference가 지워지도록 보장되므로 이론적으로 OOME [*]을 유발할 수 없습니다.

일반적인 사용 사례는 파싱 된 형식의 내용을 파일에서 유지하는 것입니다. 파일을로드하고 파싱 한 다음 구문 분석 된 표현의 루트 객체에 대한 SoftReference를 유지하는 시스템을 구현해야합니다. 다음에 파일이 필요할 때 SoftReference를 통해 파일을 검색하려고합니다. 검색 할 수 있으면 다른로드 / 파싱을 아끼지 않았으며 GC에서로드를 지우면 다시로드합니다. 이렇게하면 성능 최적화를 위해 사용 가능한 메모리를 사용하지만 OOME의 위험은 없습니다.

이제 [*]입니다. SoftReference를 유지한다고해서 OOME 자체가 발생하지는 않습니다. 반면에 실수로 약한 참조를 사용하여 작업에 약한 참조를 사용하는 경우 (즉, 개체와 관련된 정보를 어떻게 든 강력하게 참조하고 참조 개체가 지워지면 버리는 경우) OOME을 실행할 수 있습니다. ReferenceQueue를 폴링하고 관련 개체를 삭제하는 코드는 적시에 실행되지 않을 수 있습니다.

따라서 결정은 사용량에 따라 결정됩니다. 구성하는 데 비용이 많이 들지만 다른 데이터에서 재구성 할 수있는 정보를 캐싱하는 경우 소프트 참조를 사용하십시오. 일부 데이터의 정식 인스턴스에 대한 참조를 유지하거나 원하는 경우 "소유"하지 않은 객체에 대한 참조가 있으므로 (GC되지 않도록) 약한 참조를 사용하십시오.


14
약한 물체가 사용되는시기를 설명하는 데 특히 유용합니다.
Jack BeNimble

a를 올바르게 사용하는 데있어 중요한 점은 WeakReference그것을 사용해야하는 곳에서 참조가 범위를 벗어난 후에도 잠시 동안 유효하게 유지 될 수 있다는 사실은 견딜 수 있지만 바람직하지는 않다는 것입니다.
supercat 2019

항상 키 값 객체에 대한 약한 참조를 생성하는 경우 WeakHashMap의 사용이 무엇인지 이해하려고 애 쓰고 있습니다.

@supercat, GC 실행을 관찰하는 용도는 하나뿐입니다WeakReference . 정교함 참조 : stackoverflow.com/a/46291143/632951
Pacerier

1
@Pacerier : 해당 게시물의 작성자는 단순히 잘못되었습니다. 그는 이벤트 구독과 같은 다른 사용 시나리오를 무시하고, 두 번째 요점은 의미가 없으며, 세 번째 요점은 프로그래머가 불가능한 일을 할 수 있다고 가정합니다. 그의 첫 번째 요지는 합리적이지만 내가 말한 것과 직접적으로 관련이 있습니다. 예를 들어, 코드가 불변의 큰 객체 를 자주 작성 하고 비교 해야하는 경우, 코드가 존재하는지 여부에 관계없이 코드가 새 객체를 생성하면 건물 부분이 더 저렴하지만 객체와 자체 (동일한 참조) 간의 비교는 ...
supercat

155

자바에서 ; 가장 강한 것부터 가장 약한 것까지 순서가 있습니다 : 강함, 약함, 약함 및 팬텀

강한 참조는 GC에 의해 수집에서 언급 된 목적을 보호하는 정상 기준이다. 즉 가비지 수집을하지 마십시오.

소프트 참조는 가비지 컬렉터에 의해 수집 대상이지만, 아마도 메모리가 필요할 때까지 수집되지 않습니다. 즉 가비지 수집 전에 OutOfMemoryError.

약한 참조는 GC에 의해 수집에서 참조 된 개체를 보호하지 않는 기준이다. 즉 가비지 수집은 Strong 또는 Soft 참조가 없을 때 수집됩니다.

팬텀 참조는 객체에 대한 참조 phantomly가 확정 된 후에 언급하지만, 그 할당 된 메모리는 회수되기 이전이다.

출처

유추 : JVM이 왕국이고, Object가 왕국의 왕이고, GC는 왕 (객체)을 죽이려는 왕국의 공격 자라고 가정합니다.

  • 왕이 강할 때 , GC는 그를 죽일 수 없습니다.
  • King이 Soft 일 때 GC 는 그를 공격하지만 King은 자원을 사용할 수있을 때까지 왕국을 보호합니다.
  • King이 약하면 GC 는 그를 공격하지만 보호없이 왕국을 지배합니다.
  • 왕이 팬텀 일 때 , GC는 이미 그를 죽 였지만 그의 영혼을 통해 왕을 구할 수 있습니다.

7
소프트 참조 ... until memory is available의미가 없습니다. 당신은 의미 is eligible for collection by garbage collector, but probably won't be collected until its memory is needed for another use합니까?
ToolmakerSteve

1
예, 가비지 수집기는 메모리를 사용할 수있을 때까지 참조를 수집하지 않습니다.
Premraj

2
나는 나로부터 너무 많은 bla bla bla +1없이 간단한 설명 된 물건을 좋아합니다!
Adelin

3
혁신적인 사례와 우수한 요약
Ravindra babu


77

약한 참조 http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/ref/WeakReference.html

원리 : weak reference 가비지 수집과 관련이 있습니다. 일반적으로 하나 이상의 객체 reference는 가비지 수집에 적합하지 않습니다.
위의 원칙은 적용되지 않습니다 weak reference. 객체가 다른 객체와 참조가 약한 경우 가비지 수집 준비가 완료됩니다.

아래 예제를 보자 Map. Key가 객체를 참조 하는 with 객체가 있습니다.

import java.util.HashMap;   
public class Test {

    public static void main(String args[]) {
        HashMap<Employee, EmployeeVal> aMap = new 
                       HashMap<Employee, EmployeeVal>();

        Employee emp = new Employee("Vinoth");
        EmployeeVal val = new EmployeeVal("Programmer");

        aMap.put(emp, val);

        emp = null;

        System.gc();
        System.out.println("Size of Map" + aMap.size());

    }
}

이제 프로그램을 실행하는 동안 우리는 만들었습니다 emp = null. Map그대로 유지 키 여기에 이해되지 않는다 null. 위의 상황에서 개체는 가비지 수집되지 않습니다.

약한 해시지도

WeakHashMapkey-to-value mappings더 이상 에서 항목 을 검색 할 수 없을 때 항목 ( )이 제거 되는 항목 Map입니다.

위의 예제를 WeakHashMap 과 동일하게 보여 드리겠습니다.

import java.util.WeakHashMap;

public class Test {

    public static void main(String args[]) {
        WeakHashMap<Employee, EmployeeVal> aMap = 
                    new WeakHashMap<Employee, EmployeeVal>();

        Employee emp = new Employee("Vinoth");
        EmployeeVal val = new EmployeeVal("Programmer");

        aMap.put(emp, val);

        emp = null;

        System.gc();
        int count = 0;
        while (0 != aMap.size()) {
            ++count;
            System.gc();
        }
        System.out.println("Took " + count
                + " calls to System.gc() to result in weakHashMap size of : "
                + aMap.size());
    }
}

출력 :20 calls to System.gc()에서 결과 aMap size의 : 0.

WeakHashMap키에 대한 약한 참조 만 있고 다른 Map클래스 와 같은 강한 참조는 없습니다 . 값이나 키를 사용했지만 강력하게 참조 할 때주의해야 할 상황이 있습니다 WeakHashMap. 이것은 WeakReference에 객체를 랩핑함으로써 피할 수 있습니다 .

import java.lang.ref.WeakReference;
import java.util.HashMap;

public class Test {

    public static void main(String args[]) {
        HashMap<Employee, EmployeeVal> map = 
                      new HashMap<Employee, EmployeeVal>();
        WeakReference<HashMap<Employee, EmployeeVal>> aMap = 
                       new WeakReference<HashMap<Employee, EmployeeVal>>(
                map);

        map = null;

        while (null != aMap.get()) {
            aMap.get().put(new Employee("Vinoth"),
                    new EmployeeVal("Programmer"));
            System.out.println("Size of aMap " + aMap.get().size());
            System.gc();
        }
        System.out.println("Its garbage collected");
    }
}

소프트 레퍼런스.

Soft Reference약한 참조보다 약간 강합니다. 소프트 참조는 가비지 콜렉션을 허용하지만 다른 옵션이없는 경우에만 가비지 콜렉터에서이를 지우도록 요청합니다.

가비지 수집기는 약한 도달 가능한 객체와는 달리 부드럽게 도달 가능한 객체를 적극적으로 수집하지 않고 실제로 메모리에 "필요한"경우에만 도달 가능한 부드러운 객체를 수집합니다. 소프트 참조는 가비지 콜렉터에게 말하는 방법입니다. "메모리가 너무 빡빡하지 않으면이 오브젝트를 유지하고 싶습니다. 그러나 메모리가 정말 빡빡하면 계속해서 수집하여 처리하겠습니다. 그것으로." 가비지 수집기는 모든 소프트 참조를 삭제해야 던져 질 수 있습니다 OutOfMemoryError.


5
당신은 얻을 수 NullPointerException있는을 aMap.get().put(...).
xehpuk

첫 번째 HashMap 예제가 잘못 보입니다. "aMap.put (emp, val);"을 수행 할 때 'emp'와 'val'은 모두 강력한 참조입니다. 내부적으로 'emp = null;'을 수행 할 때 'emp'및 'val'을 보유하도록 새 변수가 작성됩니다. "emp"변수를 무효화하지만 해시 맵 내부의 변수 (여전히 원래 Employee 객체를 보유하고 있음)는 무효화합니다. 따라서 해시 맵은 외부에서 'emp'변수로 수행하는 작업에 관계없이 여전히 'emp'에 대한 강력한 참조를 보유합니다.
Tiago

@ 티아고. 아니요. 아마도 "첫 번째 예"는 WeakHashMap예를 나타냅니다 (약한 동작을 보여주는 첫 번째 예이므로). "의 WeakHashMap"에 대한 문서에서 봐 : "An entry in a WeakHashMap will automatically be removed when its key is no longer in ordinary use. " 의 WeakHashMap를 사용하는 전체 포인트는 것입니다 당신이 패스에 WeakReference를 / 선언 할 필요는 없습니다; WeakHashMap은 내부적으로이를 수행합니다. docs.oracle.com/javase/7/docs/api/java/util/WeakHashMap.html
ToolmakerSteve

System.gc ()를 0으로 호출하여 weakHashMap 크기를 다음과 같이 생성했습니다. 0은 두 번째 프로그램의 출력입니까?
Adelin

1
또 다른 예를 들어 WeakHashMap항목 만 제거하는 방법을 예제 응용 프로그램을 보여주는 행동에, 가비지 콜렉션이 실행 참조 내 대답 질문에이 IS의 WeakHashMap은 계속 성장하거나 쓰레기 키를 삭제합니까? .
Basil Bourque

50

소프트 레퍼런스와 약한 레퍼런스의 유일한 차이점은

가비지 콜렉터는 알고리즘을 사용하여 부드럽게 도달 가능한 오브젝트를 회수할지 여부를 결정하지만 항상 약한 도달 가능한 오브젝트를 회수합니다.


@ATorras, 사미르. 나는이 답변을 여기에서 확장했습니다 : stackoverflow.com/a/46291143/632951
Pacerier

25

SoftReference캐시 용으로 설계되었습니다. WeakReference도달 할 수없는 객체를 참조하는 것이 발견 되면 즉시 지워집니다. SoftReference그대로 남아있을 수 있습니다. 일반적으로 사용 가능한 메모리 양과 메모리를 지 울지 여부를 결정하는 데 사용 된 시간과 관련된 일부 알고리즘이 있습니다. 현재 Sun 알고리즘은 Java 힙에 사용 가능한 메가 바이트의 메모리가있는 시간 (초)에 사용되지 않은 경우 참조를 지우는 것 -Xmx입니다. SoftReferences OutOfMemoryError도달 할 수없는 한 s가 처리되기 전에 지워집니다 .


9
그러나 안드로이드에서는 캐시에 대한 권고하지 않습니다 developer.android.com/reference/java/lang/ref/...
야로 슬라브 Mytkalyk에게

4
@DoctororDrive tbf 질문은 dalvik이 아닌 java에 관한 것입니다! - P
fabspro

2
@YaroslavMytkalyk, 솔직히 Android가 클래스의 동작을 다시 작성하려면 자체 네임 스페이스를 사용해야합니다 java.lang. 이러한 동의어의 남용은 아무 소용이 없습니다.
Pacerier

9

기사 는 강력하고 부드럽고 약하며 팬텀 참조를 이해하는 데 도움 이 될 수 있습니다.


요약하면

개체에 대한 참조약한 경우 (강한 참조가없는 경우) 다음 GC주기에서 GC가 개체를 회수합니다.

객체에 대한 소프트 참조 만있는 경우 (강한 참조가없는 경우) JVM에 메모리가 부족할 때만 GC가 객체를 회수합니다.


따라서 강력한 참조는 궁극적 인 힘 을가집니다 (GC에서 수집 할 수 없음).

소프트 참조는 약한 참조보다 강력합니다 (JVM에 메모리가 부족할 때까지 GC주기를 벗어날 수 있음)

약한 참조는 소프트 참조보다 훨씬 강력 하지 않습니다 (GC주기를 초과 할 수 없으며 객체에 다른 강한 참조가없는 경우 회수 됨).


식당 비유

  • 웨이터-GC
  • 당신-힙의 객체
  • 식당 지역 / 공간-힙 공간
  • 신규 고객-식당에서 테이블을 원하는 새로운 객체

이제 당신이 강한 고객 이라면 (강한 참조와 유사하다), 새로운 고객이 식당에 오거나 그와 비슷한 일이 있어도 테이블 (메모리 영역은 힙)을 떠나지 않을 것입니다. 웨이터는 식당을 떠나라고 말할 권리가 없습니다.

당신이 경우 소프트 고객 (소프트 참조 유사)을 새로운 고객이 레스토랑에서 오는 경우 새로운 고객을 수용 왼쪽으로 다른 빈 테이블이없는 경우를 제외하고, 웨이터가 테이블을 떠나하도록 요구하지 않습니다. (즉, 웨이터는 새로운 고객이 들어오고이 새로운 고객을 위해 다른 테이블이 남아 있지 않은 경우에만 테이블을 떠나도록 요청합니다)

당신이 약한 고객 (약한 참조와 유사)이라면, 웨이터는 (언제든지) 레스토랑을 떠나라고 요청할 수 있습니다 : P


7

유일한 차이

다큐먼트 , 느슨한있는 WeakReferences이 있어야 실행중인 GC에 의해 삭제 될 수있다.

doc 당 , 느슨한 SoftReferences OOM이 발생하기 전에 지워 져야합니다 .

이것이 유일한 차이점입니다. 그 밖의 모든 것은 계약의 일부가 아닙니다. (최신 문서는 계약이라고 가정합니다.)

SoftReferences가 유용합니다. 메모리에 민감한 캐시는 약한 참조가 아닌 SoftReference를 사용합니다.


유일한 적절한 WeakReference를 사용하면 GC의 실행을 관찰하는 것입니다. 객체가 즉시 범위를 벗어난 새로운 WeakReference를 생성 한 다음 null을 얻으려고 시도합니다 weak_ref.get(). 이 때 null, 당신은이 기간, GC가 실행 된 사이에 그 내용.

WeakReference 를 잘못 사용하면 목록은 끝이 없습니다.

  • 형편 해킹 당신이 하나를 작성하지 않아도되도록 우선 순위 2하는 SoftReference를 구현하는, 그러나 그것은 캐시에서 삭제 될 수 있기 때문에 예상대로 작동하지 않습니다 모든 여분의 메모리가있는 경우에도, GC 실행. phails에 대해서는 https://stackoverflow.com/a/3243242/632951 을 참조 하십시오 . (또한, 2 단계 이상의 캐시 우선 순위가 필요한 경우 어떻게해야합니까? 여전히 실제 라이브러리가 필요합니다.)

  • 데이터를 기존 클래스의 객체와 연결하기위한 거친 해킹 이지만 GC가 약한 참조가 생성 된 후 휴식을 취하기로 결정할 때 메모리 누수 (OutOfMemoryError)를 생성합니다. 게다가, 그것은 추악한 것 이상입니다 : 더 나은 접근법은 튜플을 사용하는 것입니다.

  • 데이터를 기존 클래스의 객체와 연결하기위한 거친 해킹. 클래스는 서브 클래스화할 수없는 신경을 가지고 있으며 호출해야하는 기존 함수 코드 에서 사용됩니다 . 이러한 경우 적절한 해결책은 클래스를 편집하여 서브 클래스 가능하게 만들거나, 함수를 편집하여 클래스 대신 인터페이스를 사용하거나 대체 함수를 사용하는 것입니다.


키 유형 equals()이 단지 객체 아이덴티티 인 캐시 는 어떻습니까? 핵심 객체에 더 이상 접근 할 수 없으면 소프트 매핑은 낭비되는 것처럼 보입니다.
HighCommander4

동의하지 않습니다. 어쨌든 GC에 영향을 미치지 않으려면 WeakReference를 사용하십시오 (객체 참조를 저장 한 다음 선호도가없는 경우 여전히 존재하는지 나중에 확인하십시오). GC에 영향을 미쳐 객체를 유지하려고 시도하는 경우 (즉, GC가 객체를 유지하기를 원하는 경우) SoftReference를 사용하십시오.
David Refaeli

WeakReference를 사용하는 좋은 예는 Android의 AsyncTask에 있습니다-컨텍스트 인스턴스를 유지하는 것입니다. 이렇게하면 컨텍스트가 중단되면 (활동-화면 회전 등) AsyncTask에 대한 강한 참조가 없으므로 가비지 수집 될 수 있습니다. youtu.be/…
David Refaeli

3

Java에서 6 가지 유형의 객체 도달 가능성 상태 :

  1. 강력한 LY 도달 객체 - GC가 되지 않습니다 수집 ( 메모리가에 의해 점령 되 객체의 종류). 이것들은 루트 노드 또는 다른 강력한 객체 (예 : 로컬 변수, 클래스 변수, 인스턴스 변수 등)를 통해 도달 할 수 있습니다 .
  2. 쉽게 접근 할 수있는 객체-GC 메모리 경합에 따라 이러한 종류의 객체를 수집 하려고 시도수 있습니다 . 이것들은 하나 이상의 소프트 참조 객체 를 통해 루트에서 도달 할 수 있습니다
  3. 약한 LY 도달 객체 - GC가 있어야 오브젝트의이 종류를 수집합니다. 이것들은 하나 이상의 약한 참조 객체 를 통해 루트에서 도달 할 수 있습니다
  4. 부활 가능한 객체-GC는 이미 이러한 객체를 수집하는 중입니다. 그러나 일부 파이널 라이저를 실행 하면 상태 중 하나로 돌아갈 수 있습니다-강 / 약 / 약
  5. 팬텀에 도달 할 수있는 객체-GC 는 이미 이러한 객체를 수집하는 중이며 finalizer (finallyize () 메서드 자체를 선언하면 finalizer가 실행 된 경우)에서 종료 할 수없는 것으로 확인되었습니다 . 이들은 하나 이상의 팬텀 참조 객체 를 통해 루트에서 도달 할 수 있습니다.
  6. 도달 할 수없는 개체-개체가 강하고 부드럽거나 약하거나 팬텀에 도달 할 수 없으며 부활 할 수 없습니다. 이 개체들은 교정 준비가되었습니다

자세한 내용은 https://www.artima.com/insidejvm/ed2/gc16.html «축소


4
팬텀 참조에 대한 좋은 설명이 아닙니다. 또한 4 가지 유형을 고유 한 순서로 나열했습니다. "팬텀"은 가장 강한 유형이 아니라 가장 약한 유형입니다. 이것들을 나열하는 전통적인 순서는 "강하고, 약하며, 약하고, 팬텀"입니다. 그리고 팬텀 객체가 캐싱 메커니즘에 사용된다는 개념을 어디서 얻었는지 모르겠습니다. AFAIK는 GC에서만 볼 수있는 임시 상태이며 일반 프로그래머가 사용하는 것이 아닙니다.
ToolmakerSteve

@ToolmakerSteve and all-몇 가지 사항에 대한 사과 1. 이전 답변의 이전 버전에서 팬텀 참조에 대한 잘못된 설명 및 2. 오류 수정 지연. 이제 오류를 수정하여 답변이 개선되었습니다.
V.Vidyasagar

1

약하게 참조 된 개체는 약한 참조 만있는 경우에만 수집됩니다. 하나의 강력한 참조가있는 경우, 약한 참조가 몇 개 있더라도 수집되지 않습니다.


이것은 상식입니다 ... softref와 phantomref도 마찬가지입니다.
Pacerier

1

작동중인 메모리 사용 측면을 제공하기 위해 프로그램이 끝날 때까지 무거운 객체를 사용하여 무거운 물건으로 무거운 하중을받는 Strong, Soft, Weak & Phantom 참조를 실험했습니다. 그런 다음 힙 사용 및 GC 동작을 모니터링했습니다 . 이러한 측정 항목은 사례마다 다를 수 있지만 확실히 높은 수준의 이해를 제공합니다. 결과는 다음과 같습니다.

고하 중에서 힙 및 GC 동작

  • Strong / Hard Reference- 프로그램이 계속됨에 따라 JVM은 보유 된 강력한 참조 오브젝트를 수집 할 수 없습니다. 결국 "java.lang.OutOfMemoryError : Java heap space"에서 종료되었습니다.
  • Soft Reference- 프로그램이 계속 진행되면서 힙 사용량은 계속 증가했지만 최대 힙에 가까워지면 OLD gen GC가 발생했습니다. GC는 프로그램을 시작한 후 조금 후에 시작되었습니다.
  • 약한 참조 -프로그램이 시작될 때 객체가 마무리되고 거의 즉시 수집되기 시작했습니다. 대부분의 개체는 젊은 세대 가비지 수집에서 수집되었습니다.
  • 팬텀 레퍼런스 -약한 레퍼런스와 마찬가지로 팬텀 레퍼런스 객체도 최종화 및 가비지 수집을 즉시 시작했습니다. 구세대 GC가 없었으며 모든 객체는 젊은 세대 가비지 수집 자체에서 수집되었습니다.

이 실험에 대한 깊이 그래프, 통계, 관측치에 대한 자세한 내용은 여기를 참조하십시오 .


0

WeakReference를 : 약하게 참조하는 객체가 모든 GC주기에 수집 (미성년자 또는 전체).

SoftReference : 부드럽게 참조되는 오브젝트가 수집되는시기는 다음에 따라 다릅니다.

  1. -XX : SoftRefLRUPolicyMSPerMB = N 플래그 (기본값은 1000, 일명 1 초)

  2. 힙에서 사용 가능한 메모리의 양입니다.

    예:

    • 힙에는 10MB의 여유 공간이 있습니다 (전체 GC 후).
    • -XX : SoftRefLRUPolicyMSPerMB = 1000

    SoftReference가 참조한 오브젝트는 마지막으로 액세스 한 시간이 10 초보다 크면 수집됩니다.

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