如何在 Java 中清除软引用?
我有一个缓存,其中包含对缓存对象的软引用.我正在尝试为使用缓存的类的行为编写功能测试,专门用于清除缓存对象时发生的情况.
I have a cache which has soft references to the cached objects. I am trying to write a functional test for behavior of classes which use the cache specifically for what happens when the cached objects are cleared.
问题是:我似乎无法可靠地清除软引用.简单地用完一堆内存并不能解决问题:在清除任何软引用之前,我得到了 OutOfMemory.
The problem is: I can't seem to reliably get the soft references to be cleared. Simply using up a bunch of memory doesn't do the trick: I get an OutOfMemory before any soft references are cleared.
有什么方法可以让 Java 更积极地清理软引用?
Is there any way to get Java to more eagerly clear up the soft references?
找到 这里:
虽然可以保证所有SoftReferences 将在之前被清除OutOfMemoryError 被抛出,所以他们理论上不会导致OOME."
"It is guaranteed though that all SoftReferences will get cleared before OutOfMemoryError is thrown, so they theoretically can't cause an OOME."
那么这是否意味着上述情况一定意味着我在某个地方存在内存泄漏,并且某个类在我的缓存对象上持有硬引用?
So does this mean that the above scenario MUST mean I have a memory leak somewhere with some class holding a hard reference on my cached object?
推荐答案
问题是:我似乎不能可靠地获得软引用清除.
The problem is: I can't seem to reliably get the soft references to be cleared.
这不是 SoftReferences 独有的.由于 Java 中垃圾收集的性质,不能保证任何可垃圾收集的东西实际上会在任何时间点被收集.即使是简单的代码:
This is not unique to SoftReferences. Due to the nature of garbage collection in Java, there is no guarantee that anything that is garbage-collectable will actually be collected at any point in time. Even with a simple bit of code:
Object temp = new Object();
temp = null;
System.gc();
无法保证第一行中实例化的对象在此时或实际上在任何时候都会被垃圾回收.这只是在内存管理语言中你必须忍受的事情之一,你放弃了对这些事情的声明权.是的,这有时会导致很难明确地测试内存泄漏.
there is no guarantee that the Object instantiated in the first line is garbage collected at this, or in fact any point. It's simply one of the things you have to live with in a memory-managed language, you're giving up declarative power over these things. And yes, that can make it hard to definitively test for memory leaks at times.
也就是说,根据您引用的 Javadocs,在抛出 OutOfMemoryError 之前绝对应该清除 SoftReferences(事实上,这是它们的全部意义,也是它们与默认对象引用不同的唯一方式).因此,听起来好像存在某种内存泄漏,因为您持有对相关对象的更硬引用.
That said, as per the Javadocs you quoted, SoftReferences should definitely be cleared before an OutOfMemoryError is thrown (in fact, that's the entire point of them and the only way they differ from the default object references). It would thus sound like there is some sort of memory leak in that you're holding onto harder references to the objects in question.
如果你对 JVM 使用 -XX:+HeapDumpOnOutOfMemoryError
选项,然后将堆转储加载到类似 jhat,您应该能够看到对您的对象的所有引用,从而查看除了您的软引用之外是否还有任何引用.或者,您可以在测试运行时使用分析器实现相同的目的.
If you use the -XX:+HeapDumpOnOutOfMemoryError
option to the JVM, and then load the heap dump into something like jhat, you should be able to see all the references to your objects and thus see if there are any references beside your soft ones. Alternatively you can achieve the same thing with a profiler while the test is running.
相关文章