我知道,只有当JVM内存不足时,软引用才会发布。我怎么才能手动完成呢?
我的代码:
Object object = new Object();
ReferenceQueue queue = new ReferenceQueue();
SoftReference softReference= new SoftReference(object, queue);
object = null;
System.gc();
//now I force release soft reference.
在最新的java版本(8-11)中有解决方案吗?
发布于 2019-02-14 14:19:30
正如您所说,当存在内存压力时,软可达对象就会被收集起来,而执行此操作的一种方法是创建实际的内存压力。
例如,以下代码
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();
当软引用是对对象的唯一引用时,清除它使对象也有资格进行正常的垃圾收集,而不管实际内存压力如何。
发布于 2019-02-13 22:30:55
System.gc()
可能永远不会运行。-XX:SoftRefLRUPolicyMSPerMB=2500
参数。这意味着任何软引用项都将在2.5秒内被删除。希望这能帮上忙。发布于 2019-02-13 22:11:27
System.gc();
只建议JVM运行GC。only when I have no memory
-这是不对的。GC的工作比这更复杂,并且在JVM级别上有大量的GC设置.https://stackoverflow.com/questions/54680137
复制相似问题