0

1 행과 2 행을 주석 처리하지 않으면 1 행이 OutOfMemoryError가됩니다. 그 반대의 경우, 키, 값 >이 WeakReference에 래핑되기 때문에 OutOfMemoryError가 발생하지 않습니다. 그러나 나는 3 호선의 출력을 이해할 수 없다. - i : 3869 Size : 3870 maxSize : 3870. 자바 문서에서Java에서 맵 크기가 잘못되었습니다. WeakReference에서 키와 값을 래핑 한 다음 HashMap에 추가하면 인쇄 된 크기가 예상보다 다릅니다

:

가비지 컬렉터는 언제라도 키를 폐기 할 수 있기 때문에 알 수없는 스레드가 자동으로 항목을 제거하고 그래도 같이의 WeakHashMap가 작동 할 수 있습니다.

이 문구 크기는 줄여야하지만 줄 3 출력은 계속 증가하는 것으로 보입니다. 왜 그렇게?

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

public class WrongWeakHashMapSize { 

private static Map map = new HashMap(); 

public static void main(String[] args) { 
    for (int i = 0, maxSize = 0; i < 10000000L; ++i) { 
     /* 
     * Line 1 Causes java.lang.OutOfMemoryError: Java heap space Error. 
     * After this line i : 244 Size : 490 maxSize : 490. 
     */ 
     map.put(new LargeObject(i), new Integer(i)); // Line 1 
     /* After Commenting Line 1 :---- 
     * Line 2 Does not Cause java.lang.OutOfMemoryError. Because of WeakReference class use.I think Line 3 
     * is showing wrong Size of MAP. it printed 
     * i : 3869 Size : 3870 maxSize : 3870 which seems almost impossible 
     * because 3870 objects of LargeObject can not be exist at a time. 
     */ 
     map.put(new WeakReference(new LargeObject(i)), new WeakReference(new Integer(i))); // Line 2 
     maxSize = maxSize < map.size() ? map.size() : maxSize; // Line 3 
     System.out.println("i : " + i + " Size : " + map.size() + " maxSize : " + maxSize); // Line 4 
    } 
} 

public static class LargeObject { 
    private final byte[] space = new byte[1024 * 1024]; 
    private final int id; 

    public LargeObject(int id) { 
     this.id = id; 
    } 

    public int getId() { 
     return id; 
    } 
} 
} 
+1

WeakHashMap을 사용하지 않고 일반적인 'HashMap'을 사용합니다. 왜 WeakHashMap의 동작을 기대합니까? –

+0

@MarkRotteveel 퍼포먼스의 차이를보고 싶습니다.이 구현을 사용하면 어떤 차이가 있는지 알고 싶습니다. – HakunaMatata

답변

3

왜냐하면 map.size()은지도에서 키 - 값 쌍의 수를 제공하기 때문입니다. 가베지 컬렉션 weak 참조 지도에서 참조를 제거하지 않습니다, 그것은 단지 개체를 쓰레기 것입니다.

LargeObjectInteger 중 일부는 삭제 대상이되며 키 - 값 매핑은 여전히지도에 포함되어 있으므로 여전히 계산됩니다.

0

크기지도 구현 내부 INT 필드이며, GC가

룩의 WeakHashMap # 1 크기()를 참조 구현 수집있는 WeakReferences 및 재검 의 WeakHashMap 저장 큐에 WeakReference를

을 제거한 후이를 감소하지 않기 때문에 크기 주문형 크기

0

출처 : http://weblogs.java.net/blog/2006/05/04/understanding-weak-references 참조 큐

WeakReference를가 null 반환이 시작되면, 그것이 가리키는 객체가되었다하는 쓰레기와 WeakReference를 개체는 거의 쓸모가 없다. 이것은 일반적으로 일종의 정리가 필요하다는 것을 의미합니다. 예를 들어 WeakHashMap은 끊임없이 증가하는 죽은 WeakReference를 지키지 않으려는 이러한 잘못된 항목을 제거해야합니다.

ReferenceQueue 클래스를 사용하면 참조 불량을 쉽게 추적 할 수 있습니다. ReferenceQueue를 weak 참조의 생성자에 전달하면 참조 객체가 가리키는 객체가 불필요 해지면 참조 객체가 자동으로 참조 대기열에 삽입됩니다. 그런 다음 일정한 간격으로 ReferenceQueue를 처리하고 사용 불능 참조에 필요한 정리를 수행 할 수 있습니다.

관련 문제