代码之家  ›  专栏  ›  技术社区  ›  Minn

java中集合的WeakReference

  •  1
  • Minn  · 技术社区  · 7 年前

    背景故事

    在我维护的库中,我们有一个跟踪缓存的内部地图。 其思想是在第一次访问该列表时缓存该列表,而在第二次访问时不会有太多内存开销。 举例说明:

    List<Bob> list = cache.asList();
    List<Bob> otherList = cache.asList(); // use from cache, if still available
    

    问题是,如果不再需要这个列表,我们不想永远保留它。由于java使用GC,我们认为使用 WeakReference 为此,允许在未收集的情况下使用它。

    问题

    如果我有 WeakReference<List<Bob>> 存储在我的类中,如果其中一个元素变得弱可访问(这意味着列表是弱可访问的),会发生什么?GC是否可能决定只收集列表中的元素,或者是否会查找引用它的所有其他弱可及对象,并收集它们(在本例中为列表)?

    软引用

    3 回复  |  直到 7 年前
        1
  •  1
  •   DudeDoesThings    7 年前

    只要列表本身不是弱可及的,它的元素也不会弱可及。(假设列表实现本身不使用弱引用或类似引用)

    因此,使用弱引用缓存列表没有问题,因为它要么完全被垃圾收集,要么根本不被垃圾收集。

        2
  •  0
  •   codeformars    7 年前

    在提供的情况下( WeakReference<List<Something>> )您只有这样的可能场景:

    public class Test {
    
        private WeakReference<List<String>> listWeakReference;
    
        public Test(final WeakReference<List<String>> listWeakReference) {
            this.listWeakReference = listWeakReference;
        }
    
        public static void main(String[] args) {
            List<String> testList = Arrays.asList("a", "b", "c");
    
            Test test = new Test(new WeakReference<>(testList));
    
            // Initial check
            System.out.println(test.listWeakReference.get());
    
            // Call gc and check
            System.gc();
            System.out.println(test.listWeakReference.get());
    
            // Remove reference and call gc
            testList = null;
            System.gc();
            System.out.println(test.listWeakReference.get());
        }
    }
    
        3
  •  0
  •   Tom Hawtin - tackline    7 年前

    SoftReference 更适合缓存,即使这样也不是很好。

    WeakReference 可能会被释放 立即 引用变得弱可及。然而,它可能要到执行的某个时候才会这样做——也就是说,它不会在广泛的测试中发生,但会在生产中发生。快乐时光。NetBeans过去在文件缓存中这样做。当然,代码的其余部分期望缓存以难以置信的频率抓取和释放引用。在使用应用程序一段时间后,它会突然冲击文件I/O并变得不可用。

    回到问题上来。目录的收集 软引用 软参考 这是一个两阶段的操作。第一阶段只是清除 Reference (如果您正在使用它,则会排队)。未收集关联的内存。记忆可以通过决赛选手复活。这个 软引用

    不用担心,Java是 (虫子除外)。

    推荐文章