3

これは予想される動作である可能性がありますが、そのように記述しているドキュメントが見つかりません。グアバを使用して14.0.1います。以下の例では、キーへの強力な参照を持たないマップ内のエントリが削除されます。これは予想どおりですが、マップのサイズが同期しなくなります。

最初のチェックでは、サイズとカウントの両方が 5 です。ただし、2 番目のチェックでは、サイズは 5 と報告されますが、カウントは 0 です。2 番目のチェックでは、実際には何もないのにマップ サイズが 5 と報告されるのはなぜですかマップのエントリー?

import com.google.common.collect.Lists;
import com.google.common.collect.MapMaker;

import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class MapSizeCheck {
    public static void main(String[] args) {
        keepReferencesAndCheckSize();
        System.out.println();
        discardReferencesAndCheckSize();
    }

    private static void keepReferencesAndCheckSize() {
        Map<Object,Object> map = new MapMaker().weakKeys().makeMap();
        List<Object> refs = Lists.newArrayList();

        for(int i=0;i<5;i++) {
            Object key = new Object();
            Object value = new Object();

            map.put(key, value);
            refs.add(key); // Hold a strong reference to the key.
        }

        System.gc();

        int size = map.size();
        int count = 0;

        Iterator<Object> it = map.keySet().iterator();
        while(it.hasNext()) {
            count++;
            it.next();
        }

        System.out.println("Size  : " + size);
        System.out.println("Count : " + count);
    }

    private static void discardReferencesAndCheckSize() {
        Map<Object,Object> map = new MapMaker().weakKeys().makeMap();

        for(int i=0;i<5;i++) {
            Object key = new Object();
            Object value = new Object();

            map.put(key, value);
        }

        System.gc();

        int size = map.size();
        int count = 0;

        Iterator<Object> it = map.keySet().iterator();
        while(it.hasNext()) {
            count++;
            it.next();
        }

        System.out.println("Size  : " + size);
        System.out.println("Count : " + count);
    }
}
4

1 に答える 1