简体   繁体   English

为什么我的 WeakHashMap 条目没有被 GC 删除?

[英]Why my WeakHashMap entry doesn't be removed by GC?

I have a class to manage lock objects of several features.我有一个类来管理几个功能的锁对象。 I've figured out that WeakHashMap should fit my requirement.我发现 WeakHashMap 应该符合我的要求。 Here is my code:这是我的代码:

public static class FeatureLockManager {
        private final Map<Object, WeakKeyLockPair> locks;
        private String domain;

        public FeatureLockManager(String domain) {
            this.domain = domain;
            locks = new WeakHashMap<Object, WeakKeyLockPair>();
        }

        public Lock getLock(Object feature) {
            if (locks.get(feature) == null) {
                synchronized (locks) {
                    locks.computeIfAbsent(feature, l -> new WeakKeyLockPair(feature, new ReentrantLock()));
                }
            }
            return locks.get(feature);
        }

        private static class WeakKeyLockPair implements Lock {
            private final Reference<Object> feature;
            private final Lock lock;

            private WeakKeyLockPair(Object feature, Lock lock) {
                this.feature = new WeakReference<Object>(feature);
                this.lock = lock;
            }
...      }
       }

However, after making a simple test, I realized that lock object won't be removed after GC.然而,经过简单的测试,我发现锁对象在GC之后并不会被移除。

public static void main(String[] args) throws InterruptedException {
        FeatureLockManager test = new FeatureLockManager("test");
        Lock lock = test.getLock("add user");
        System.out.println(lock.hashCode());
        // do thing
        System.gc();
        Thread.sleep(1000);
        Lock lock1 = test.getLock("add user");
        System.out.println(lock1.hashCode());
        System.out.println(lock1 == lock);
    }

Could you please tell me that what's wrong with my implementation?你能告诉我我的实施有什么问题吗? Thank you in advance!先感谢您!

According to the java documentation of the WeakHashMap根据 WeakHashMap 的 java 文档

Each key object in a WeakHashMap is stored indirectly as the referent of a weak reference. WeakHashMap 中的每个键对象都间接存储为弱引用的引用。 Therefore a key will automatically be removed only after the weak references to it, both inside and outside of the map, have been cleared by the garbage collector.因此,只有在地图内部和外部对其的弱引用已被垃圾收集器清除后,才会自动删除该键。

Your FeatureLockManager class still has a strong reference to the key element ("add user") of the WeakHashMap.您的 FeatureLockManager 类仍然具有对 WeakHashMap 的关键元素(“添加用户”)的强引用。

For more details, check the documentation有关详细信息,请查看文档

I think that is because you are using String as a key in your map, Strings are stored in the general string pool memory, and the same literal value would be used by different parts of the program so it won't become eligible for GC, I would recommend using different object type or primitive wrapper types (try integer representation for instance) or any other object other than string我认为那是因为您在映射中使用字符串作为键,字符串存储在通用字符串池内存中,程序的不同部分将使用相同的文字值,因此它不符合 GC 的条件,我建议使用不同的对象类型或原始包装器类型(例如尝试整数表示)或字符串以外的任何其他对象

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM