为了执行一些测试,我想检查当我存储在 SoftReference 对象缓存中的部分或全部对象被处置时我的应用程序的行为。
为了做到这一点,我想手动清除存储在缓存的 SoftReference 对象中的引用 - 模拟 VM 处理这些对象 - 但前提是当前没有其他任何东西对该对象具有强引用(如果另一个进程最近从缓存中检索了引用的对象)。
我的应用程序是单线程的,所以我不需要担心缓存对象的软可达性会随着代码的执行而改变。这也意味着我目前没有任何锁定机制 - 如果我有,我可能已经使用这些来确定一个对象是否“正在使用”并因此可以强访问,但可惜我不需要这种锁定。
我尝试过的一种方法是为存储在缓存中的每个对象创建一个额外的 SoftReference,该缓存已注册到 ReferenceQueue。我希望这样做时,缓存中的所有软可访问对象都会将它们的附加 SoftReference 添加到队列中,所以我所要做的就是遍历队列,并从缓存中删除这些对象。但是,似乎 GC 在闲暇时会将可轻松访问的对象排入其各自的队列,因此一旦我完成对缓存中的对象的迭代,就不能保证任何东西都会添加到队列中。
我还看过的一件事是 -XX:SoftRefLRUPolicyMSPerMB JVM 选项,它的值非常小。通过明智的内存分配,这很可能会在软可访问的那一刻为我从缓存中清除软可访问的对象,但我真的希望应用程序正常运行,直到我收到从缓存中清除软可访问对象的请求. 作为 JVM 选项,我不相信我可以在我的应用程序运行时更改此值。
那么,是否有人对我如何确定一个对象是否只能轻触(因此可以清除)有任何想法?
编辑:可能还不清楚的一些额外点:
- 当我想清除这些软引用对象时,该应用程序可能会做有用的工作。所以我宁愿不要尝试让 GC 为我清除对象。
- 如果我可以选择清除哪些可轻松到达的对象,那将是更可取的。
- 我想让应用程序正常运行,即使用生产内存设置。更改代码中的设置,然后可以将其重置回其生产值,这很好。