开发者

When does 'Reference object' can be reclaimed?

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 SoftRefer开发者_如何学Goence, 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!


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


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)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜