java - SoftReference<String> 内存不足时未进行垃圾回收

标签 java garbage-collection soft-references

我正在为缓存实现测试 SoftReference,我发现了一个奇怪的行为:

我有一个 setName(String name) 方法,它通过 SoftReference 设置 Graph 对象的名称:

public void setName(String newName) {
    getData().name = new SoftReference<String>(newName,garbagedData);
}

(garbagedData 是一个 ReferenceQueue,在这个特定问题中似乎并不重要)。

当我从主线程调用 graph.setName("name"); 时,当强制出现 OutOfMemory 错误时,引用指向的值不会被垃圾化但是如果我调用 graph.setName(new String("name")) 那么它就是。

我使用 Eclipse Memory Analyzer 查看堆内容,在这两种情况下,除了 Soft 链之外没有其他引用链。

如果有人对我感兴趣的这种奇怪行为有解释。

最佳答案

这很简单。源代码中出现的字符串是intern ed,即保存在一个特殊的池中,并且没有机会收集它,因为它被您的方法代码引用。再次调用 setName 时需要它,所以它显然不是垃圾。

new String("name") 的情况非常不同,因为它创建了原始字符串的副本。实际上,自 this change 以来就没有必要使用这个构造函数了。到 String.substring

我猜 Eclipse 内存分析器不会显示字节码中包含的引用(因为没有人真正需要它)。

关于java - SoftReference<String> 内存不足时未进行垃圾回收,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21615718/

相关文章:

java - Java Flight Recorder 结果中的垃圾收集统计信息

java - 在 Java 中实现回写缓存

java - 单击 JTable 标题时排序错误的列

java - 模型未保存在 Play Framework 中

java - 将 double 转换为 int

java - 使用 Java 中的任何替代 DataStructure 优化 Nested-if

Java垃圾回收 "real"时间比 "user"大很多 +"system"

python - dict 不引用元素? Python2.7 改变了行为

Android:GC 不尊重 SoftReferences?

.net - .NET 有软引用吗?