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