【问题标题】:Is there any way to determine if an object in Java is softly reachable?有什么方法可以确定 Java 中的对象是否可轻松访问?
【发布时间】:2010-10-26 11:24:03
【问题描述】:

为了执行一些测试,我想检查当我存储在 SoftReference 对象缓存中的部分或全部对象被处置时我的应用程序的行为。

为了做到这一点,我想手动清除存储在缓存的 SoftReference 对象中的引用 - 模拟 VM 处理这些对象 - 但前提是当前没有其他东西对该对象有强引用(可能是如果另一个进程最近从缓存中检索了引用的对象的情况。

我的应用程序是单线程的,所以我不需要担心缓存对象的软可访问性会随着代码的执行而改变。这也意味着我目前没有任何锁定机制 - 如果我有,我可能已经使用这些来确定一个对象是否正在“被使用”并因此可以强烈访问,但可惜我不需要这种锁定。

我尝试过的一种方法是为缓存中存储的每个对象创建一个额外的 SoftReference,该缓存已注册到 ReferenceQueue。我希望这样做时,缓存中的所有软可访问对象都会将它们的附加 SoftReference 添加到队列中,所以我所要做的就是遍历队列,并从缓存中删除这些对象。但是,似乎 GC 会在闲暇时将软可访问的对象排入各自的队列,因此不能保证一旦我完成对缓存中的对象的迭代,就会将任何内容添加到队列中。

我还看过的一件事是 -XX:SoftRefLRUPolicyMSPerMB JVM 选项,它的值非常小。通过明智的内存分配,这很可能会在软可访问的那一刻为我从缓存中清除软可访问的对象,但我真的希望应用程序正常运行,直到我收到从缓存中清除软可访问对象的请求.作为 JVM 选项,我认为我无法在应用运行时更改此值。

那么,对于我如何确定一个对象是否只能轻触(因此可以被清除),是否有人有任何想法?

编辑:可能还不清楚的几点:

  • 当我想清除这些软引用对象时,该应用程序可能会做一些有用的工作。所以我不想尝试让 GC 为我清除对象。
  • 如果我可以选择清除哪些可轻松触及的对象会更好。
  • 我想让应用程序正常运行,即使用生产内存设置。更改代码中的设置,然后可以将其重置回其生产值,这很好。

【问题讨论】:

    标签: java soft-references


    【解决方案1】:

    IIRC,在抛出 OutOfMemoryError 之前,保证(在某种意义上)软引用被清除。因此,如果您分配大量内存,如果对象没有被强引用,它们应该被清除。 (未测试。)

    【讨论】:

    • 虽然这清除任何软引用对象的缓存,但我更愿意这样做而不填满内存 - 因为该应用程序很可能正在做有用的工作同时,我不想影响它的性能。另外,我必须在分配足够的内存以清除引用之间保持平衡,但又不会导致我自己导致 OutOfMemory 错误。另外,这不会让我选择清除哪些对象。
    【解决方案2】:

    混合一些答案:正如 Tom Hawtin 所说,分配内存直到你用完内存,例如使用以下代码:

    private void doOutOfMemory() {
        try {
            List<byte[]> list = new ArrayList<byte[]>();
            while (true) {
                list.add(new byte[200 * 1024 * 1024]);
            }
        } catch (OutOfMemoryError ex) {
        }
    }
    

    如果您不想控制清除哪些对象,请对要保留的对象进行强引用。

    您也可以改用weakReferences,只调用 System.gc() 来清除它们并不能保证它们总是会被清除...

    【讨论】:

    • 虽然不能完全满足我的所有要求,但这可能是我能得到的最接近的。
    【解决方案3】:

    在测试时用弱参考系统代替您当前的软参考系统。

    一旦发生这种情况,弱引用系统将立即删除没有其他传入引用的对象,而不是等待 jvm 运行垃圾回收。

    【讨论】:

    • 不,你总是要等待GC移除对象;但是对于弱引用,应该“尽快”删除它,而对于软引用,只有在 JVM 内存不足时才应该删除它......
    猜你喜欢
    • 2017-02-06
    • 2017-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-28
    • 1970-01-01
    • 2019-09-14
    相关资源
    最近更新 更多