WeakHashMap의 사용 장면

3677 단어 JAVA 베이스.
WeakHashMap을 배울 때 맵 안의 키가 맵 자체만 인용할 때 키에 대응하는 Entry를 제거한다는 것을 알게 되었다.WeakHashMap의 원본 코드를 보면 Entry가 WeakReference 클래스를 계승하고 Entry 대상을 실례화할 때 모든 키는 슈퍼 (키,queue) 방법을 호출하여 실제 대상에 대한 약한 인용으로 저장됩니다.실제로 약한 인용은 구조할 때도 하나의 대상에 강한 인용을 매개 변수로 전달해야 한다.예를 들면 다음과 같습니다.
Car car = new Car(22000,"silver");
WeakReference weakCar = new WeakReference(car);

 HashMap과 WeakHashMap의 차이점도 여기에 있다. HashMap의 키는 실제 대상에 대한 강력한 인용이다.  약한 인용 (Weak Reference) 의 특징은 gc 라인에서 약한 인용만 가리키는 것을 발견하면 메모리를 삭제하고 회수합니다.또한 참조 대기열queue에 WeakReference가 추가됩니다.  은 관련 개념을 이해한 후 WeakHashMap의 실제 응용에 대해 궁금했다.그리고tomcat의 원본에서 캐시를 실행할 때 WeakHashMap을 사용합니다.
package org.apache.tomcat.util.collections;

import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;

public final class ConcurrentCache {

    private final int size;

    private final Map eden;

    private final Map longterm;

    public ConcurrentCache(int size) {
        this.size = size;
        this.eden = new ConcurrentHashMap<>(size);
        this.longterm = new WeakHashMap<>(size);
    }

    public V get(K k) {
        V v = this.eden.get(k);
        if (v == null) {
            synchronized (longterm) {
                v = this.longterm.get(k);
            }
            if (v != null) {
                this.eden.put(k, v);
            }
        }
        return v;
    }

    public void put(K k, V v) {
        if (this.eden.size() >= size) {
            synchronized (longterm) {
                this.longterm.putAll(this.eden);
            }
            this.eden.clear();
        }
        this.eden.put(k, v);
    }
}

  원본 코드에는 eeden과 longterm의 두 개의 맵이 있는데 jvm 더미에 대해 알고 있으면tomcat은 여기에서 ConcurrentHashMap과 WeakHashMap을 사용하여 세대별 캐시를 만들었을 것으로 추정된다.put 방법에서 k-v를 삽입할 때, 먼저 eeden 캐시 용량이 초과되었는지 검사합니다.초과하지 않으면 바로 Eden 캐시에 넣고, 초과하면 longterm을 잠그고 Eden의 모든 k-v를 longterm에 넣습니다.eeden을 비우고 k-v에 삽입합니다.get 방법에서도 eeden에서 대응하는 v를 우선적으로 찾고, 없으면 롱터m 캐시에 들어가서 찾으면 eeden 캐시를 넣고 되돌려줍니다.   이러한 디자인을 통해 상대적으로 자주 사용하는 대상은 모두 eeden 캐시에서 찾을 수 있고 자주 사용하지 않는 대상은longterm 캐시에 들어간다.롱터미널의 키의 실제 대상이 다른 인용이 그를 가리키지 않을 때 gc는 hp에서 이 약한 인용이 가리키는 실제 대상을 자동으로 회수하고 약한 인용은 인용 대기열에 들어간다.longterm에서 expungeStale Entries () 방법을 호출하여 대기열의 약한 인용을 반복적으로 인용하고 대응하는 Entry를 제거하면 메모리 공간의 낭비를 초래하지 않습니다.

좋은 웹페이지 즐겨찾기