“引用对象”何时出现?可以回收吗?
现在,我遇到了这样一个奇怪的情况:
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 设置:-Xms20m -Xmx40m。当我想将许多SoftReference放入缓存时,JVM退出,没有任何提示或异常。其实我对SoftReference的作用很怀疑,它是JVM的特殊对象。谁能解释一下这个程序发生了什么?
另外两个问题: 1. JVM堆中的那些“特殊引用实例”是否有额外的内存分配方法? 2. 当它们所指向的实例已被释放时,什么时候可以释放这些引用实例?多谢!
Now, I met a strange case likes that:
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());
}
}
I have set the JVM setting:-Xms20m -Xmx40m. When I want to put many of SoftReference to cache, the JVM exit without any promption or exception. Actually, I am doubtful of the action of SoftReference, it's special object for JVM. Could anyone explains what's happen for this program?
Another two questions:
1. Does there has extra memory allocation method for those 'special reference instance' in JVM heap?
2. When does those reference instance can be freed when the instance that they pointer to has been freed? Thanks a lot!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
SoftReference 的每个实例本身占用 24 字节的堆内存(对于 32 位 Sun JVM 来说是这样,对于其他 VM 可能有所不同)。您尝试在列表中存储 3'000'000 个实例,这意味着您至少需要 ~70Mb 的堆空间来存储
SoftReference
对象。SoftReference 对象保留对软可访问对象(在您的情况下为 String )的“软引用”,并且 JVM 规范保证在虚拟机抛出异常之前这些引用将被清除(即 String 对象将被垃圾收集)一个
OutOfMemoryError
。但是,JVM 将不会垃圾收集 SoftReference 对象,因为您从缓存
列表中保留了对它们的强引用。 (因此,如果您需要从堆中删除 SoftReference 对象 - 将其从缓存
列表中删除)。Each instance of SoftReference occupies 24 bytes of heap-memory by itself (this is true for 32-bit Sun JVM, and may differ for others VMs). You are trying to store in the list 3'000'000 instances which means you will need at least ~70Mb of heap space just to store the
SoftReference
objects.SoftReference
object keeps a "soft reference" to the soft-reachable object (String in your case) and JVM spec guarantees those references will be cleared (i.e. String objects will be garbage collected) before the virtual machine throws anOutOfMemoryError
. However JVM will NOT garbage-collect SoftReference objects since you keep strong references to them from yourcache
list. (So if you need SoftReference object to be removed from the heap - remove it from thecache
list).如果我使用
-mx40m
运行这个程序,我会得到
WeakReferences 和 SoftReferences 的问题之一,它们往往会立即被清除。
尝试 WeakReference,SoftReferences 只有在确实需要时才清晰。为了更清楚地看到它们,请尝试创建一个足够大的数组来触发 OutOfMemoryError。
所有对象都在堆中。即使静态字段也被包装在堆上的伪对象中。 (后面的行为没有定义,但我看到它是如何工作的)
引用实例在被丢弃后被释放(像任何其他对象一样)
If I run this program with
-mx40m
I get
One of the problems with WeakReferences and SoftReferences is that they tend to all be cleared at once.
Try WeakReference, SoftReferences are only clear if it really has to. To see them clearer, try creating a large enough array to trigger an OutOfMemoryError.
All object are in the heap. Even static fields are wrapped in a pseudo object which is on the heap. (This later behaviour is not defined but it how I have seen it work)
The reference instance is freed after it has been discarded (like any other object)