“引用对象”何时出现?可以回收吗?

发布于 2024-12-04 12:17:17 字数 715 浏览 0 评论 0原文

现在,我遇到了这样一个奇怪的情况:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

坏尐絯 2024-12-11 12:17:17

当OOM发生时,总会有很多SoftReference实例存在,你能帮忙解释一下这种情况吗?

SoftReference 的每个实例本身占用 24 字节的堆内存(对于 32 位 Sun JVM 来说是这样,对于其他 VM 可能有所不同)。您尝试在列表中存储 3'000'000 个实例,这意味着您至少需要 ~70Mb 的堆空间来存储 SoftReference 对象。

SoftReference 对象保留对软可访问对象(在您的情况下为 String )的“软引用”,并且 JVM 规范保证在虚拟机抛出异常之前这些引用将被清除(即 String 对象将被垃圾收集)一个OutOfMemoryError。但是,JVM 将不会垃圾收集 SoftReference 对象,因为您从缓存列表中保留了对它们的强引用。 (因此,如果您需要从堆中删除 SoftReference 对象 - 将其从缓存列表中删除)。

When the OOM occurs, there always many of SoftReference instance has existing, can you help to explain this case?

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 an OutOfMemoryError. However JVM will NOT garbage-collect SoftReference objects since you keep strong references to them from your cache list. (So if you need SoftReference object to be removed from the heap - remove it from the cache list).

十级心震 2024-12-11 12:17:17

如果我使用 -mx40m 运行这个程序,

char[] chars = new char[4096];
List<SoftReference<String>> strings = new ArrayList<SoftReference<String>>();
do {
  strings.add(new SoftReference<String>(new String(chars)));
} while(strings.get(0).get()!=null);
int nulls=0, set=0;
for (SoftReference<String> string : strings) {
  if(string.get() == null) nulls++; else set++;
}
System.out.println("nulls= "+nulls+", was still set= "+set);

我会得到

nulls= 4618, was still set= 1

WeakReferences 和 SoftReferences 的问题之一,它们往往会立即被清除。


尝试 WeakReference,SoftReferences 只有在确实需要时才清晰。为了更清楚地看到它们,请尝试创建一个足够大的数组来触发 OutOfMemoryError。

  1. 所有对象都在堆中。即使静态字段也被包装在堆上的伪对象中。 (后面的行为没有定义,但我看到它是如何工作的)

  2. 引用实例在被丢弃后被释放(像任何其他对象一样)

If I run this program with -mx40m

char[] chars = new char[4096];
List<SoftReference<String>> strings = new ArrayList<SoftReference<String>>();
do {
  strings.add(new SoftReference<String>(new String(chars)));
} while(strings.get(0).get()!=null);
int nulls=0, set=0;
for (SoftReference<String> string : strings) {
  if(string.get() == null) nulls++; else set++;
}
System.out.println("nulls= "+nulls+", was still set= "+set);

I get

nulls= 4618, was still set= 1

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.

  1. 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)

  2. The reference instance is freed after it has been discarded (like any other object)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文