我只有在没有内存的情况下才知道软引用释放,但是我可以手动执行吗?
我的代码:
Object object = new Object();
ReferenceQueue queue = new ReferenceQueue();
SoftReference softReference= new SoftReference(object, queue);
object = null;
System.gc();
//now I force release soft reference.
我想发布softReference
,
我能做到吗?
最新的Java版本(8-11)是否有解决方案?
谢谢。
答案 0 :(得分:1)
System.gc()
可能永远不会运行,具体取决于启动垃圾收集之前设置的阈值。-XX:SoftRefLRUPolicyMSPerMB=2500
参数。这意味着所有软引用的项目将在2.5秒内删除。希望有帮助。 答案 1 :(得分:1)
正如您所说,当存在内存压力和 强制执行此操作的一种方法是创建实际的内存压力。
例如以下代码
Object object = new Object();
ReferenceQueue queue = new ReferenceQueue();
SoftReference softReference= new SoftReference(object, queue);
new Thread(() -> {
try {
queue.remove();
System.out.println("collected");
} catch (InterruptedException ex) {}
}).start();
object = null;
try {
object = new int[10][10][10][10][10][10][10][10][10][10][10][10];
} catch(OutOfMemoryError err) {
System.out.println("...");
}
打印
collected
...
在我的机器上。
上面的代码示例遵循以下想法:通过肯定会失败的分配请求来触发行为,但是要防止JVM检测到它永远不会成功,就像当JVM检测到分配永远不会成功时一样垃圾收集器的工作,它可能会跳过垃圾收集(并因此清除软引用)。
多维数组分配,这是Java中的数组数组,似乎使当前的实现变得足够混乱,因此实际上可以尝试。使用纯数组的另一种方法是从一个小尺寸开始循环分配,并增大直到失败。
仍然存在JVM优化器检测到从未使用过分配的对象并完全消除分配的风险,但是,对于仅执行一次的代码,这种情况很少发生。
如果唯一需要的效果是清除SoftReference
并将其排入队列,例如要测试处理代码,您只需调用clear()
,然后在引用对象上调用enqueue()
。
Object object = new Object();
ReferenceQueue queue = new ReferenceQueue();
SoftReference softReference= new SoftReference(object, queue);
new Thread(() -> {
try { queue.remove(); } catch (InterruptedException ex) {}
Object object = new Object();
ReferenceQueue queue = new ReferenceQueue();
SoftReference softReference= new SoftReference(object, queue);
new Thread(() -> {
try {
queue.remove();
System.out.println("collected");
} catch (InterruptedException ex) {}
}).start();
object = null;
Thread.sleep(500);
softReference.clear();
softReference.enqueue();
当软引用是对对象的唯一引用时,清除它会使该对象也有资格进行正常的垃圾回收,而不管实际的内存压力如何。
答案 2 :(得分:0)
通常,您不能:System.gc();
仅建议JVM运行GC
only when I have no memory
-这是完全不对的。 GC的工作原理要复杂得多,并且在JVM级别上还有很多GC的设置...