现在,我遇到了这样一个奇怪的情况:
public class SoftRefDemo {
private static List<SoftReference<String>> cache;
public static void main(String[] args) {
int total = 3000000;
cache = new ArrayList<SoftReference<String>>(total);
for (int i = 0; i < total; i++) {
cache.add(new SoftReference<String>("fafsfsfsdf" + i));
}
System.out.println(cache.size());
}
}
我已经设置了JVM设置:-Xms 20 m-Xmx 40 m。当我想把很多SoftReference放到缓存中时,JVM没有任何提示或异常就退出了。实际上,我对SoftReference的行为表示怀疑,它是JVM的特殊对象。有人能解释一下这个程序发生了什么吗?
**另外两个问题:**1. JVM堆中的那些“特殊引用示例”是否有额外的内存分配方法?2.当那些引用示例所指向的示例被释放后,它们什么时候才能被释放?谢谢!
2条答案
按热度按时间q8l4jmvw1#
当出现对象模型时,总是有很多SoftReference示例已经存在,你能帮助解释这种情况吗?
SoftReference的每个示例本身占用24字节的堆内存(这对于32位Sun JVM是真实的,对于其他VM可能会有所不同)。您尝试在列表中存储3 '000'000个示例,这意味着您将至少需要~ 70 Mb的堆空间来存储
SoftReference
对象。SoftReference
对象保留对软可访问对象的“软引用(本例中为字符串),JVM规范保证将清除这些引用(即字符串对象将被垃圾收集)。但是,JVM不会对SoftReference对象进行垃圾收集,因为您保留了cache
列表中对它们的强引用。(因此,如果您需要从堆中删除SoftReference对象,请从cache
列表中删除它)。qrjkbowd2#
如果我用
-mx40m
运行这个程序我得到
WeakReferences和SoftReferences的问题之一是它们往往会被一次性清除。
尝试WeakReference,SoftReferences只有在必要时才是透明的。要更清楚地查看它们,请尝试创建一个足够大的数组来触发OutOfMemoryError。
1.所有对象都在堆中。甚至静态字段也被 Package 在堆中的伪对象中。(后面的行为没有定义,但我已经看到它是如何工作的)
1.引用示例在被丢弃后被释放(与任何其他对象一样)