首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何强制释放软引用?

如何强制释放软引用?
EN

Stack Overflow用户
提问于 2019-02-13 22:01:48
回答 3查看 790关注 0票数 1

我知道,只有当JVM内存不足时,软引用才会发布。我怎么才能手动完成呢?

我的代码:

代码语言:javascript
运行
复制
  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)中有解决方案吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-02-14 14:19:30

正如您所说,当存在内存压力时,软可达对象就会被收集起来,而执行此操作的一种方法是创建实际的内存压力。

例如,以下代码

代码语言:javascript
运行
复制
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("...");
}

版画

代码语言:javascript
运行
复制
collected
...

在我的机器上。

上面的代码示例遵循这样的想法:通过一个肯定会失败的分配请求来触发行为,但是为了防止JVM检测到它永远不会成功,因为当JVM检测到一个分配永远不会成功时,不管垃圾收集器的努力如何,它可能跳过垃圾收集(因此,清除软引用)。

多维数组分配是Java中的一个数组,它似乎对当前的实现有足够的混淆,所以它确实尝试了。使用普通数组的另一种方法是在循环中分配,从较小的大小开始,直到失败为止。

JVM的优化器仍然可能检测到分配的对象从未被使用过,并且完全消除了分配,然而,对于只执行一次的代码,很少会发生这种情况。

如果唯一想要的效果是清除SoftReference并排队,例如测试处理代码,您可以简单地调用clear(),然后在引用对象上使用enqueue()

代码语言:javascript
运行
复制
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
EN

Stack Overflow用户

发布于 2019-02-13 22:30:55

  • 根据垃圾收集启动之前设置的阈值,System.gc()可能永远不会运行。
  • 一个选项是调整JVM配置中的-XX:SoftRefLRUPolicyMSPerMB=2500参数。这意味着任何软引用项都将在2.5秒内被删除。希望这能帮上忙。
票数 4
EN

Stack Overflow用户

发布于 2019-02-13 22:11:27

  1. 一般来说,您不能:System.gc();只建议JVM运行GC。
  2. only when I have no memory -这是不对的。GC的工作比这更复杂,并且在JVM级别上有大量的GC设置.
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54680137

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档