سؤال

I am testing SoftReference for a cache implementation and I found a strange behaviour :

I have a setName(String name) method which sets the name of a Graph object through a SoftReference :

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

(garbagedData is a ReferenceQueue and doesn't seem important in this particular problem).

When I call graph.setName("name"); from main thread, and when à force a OutOfMemory error, the value pointed by the reference is not garbaged but if I call graph.setName(new String("name")) then it is.

I look the heap contents with Eclipse Memory Analyzer and in both case there is no other reference chain than the Soft one.

If anyone has an explanation for this strange behavior I am interested.

هل كانت مفيدة؟

المحلول

That's pretty simple. The string appearing in the source code is interned, i.e., kept in a special pool, and there's no chance to collect it as it's referenced by the code of your method. It's needed when setName gets called again, so it's obviously no garbage.

The situation with new String("name") is very different as this creates a copy of the original String. Actually, there's no need to use this constructor since this change to String.substring.

I guess the Eclipse Memory Analyzer doesn't show references contained in the bytecode (as nobody really needs it).

نصائح أخرى

You are holding a SoftReference to String object. For a String object JVM manages String literals differently from String objects.

String a = new String("test");
String b = new String("test");

In this example instances a and b are references to different objects.

String a = "test";
String b = "test";

Here both a and b are references to same String literal. When you call graph.setName("name"), it is creating a reference to string literal. String objects that refer to String literals generally are not considered for garbage collection. This prevents the String object from getting garbage collected.

When you call graph.setName(new String("name")), it is creating a SoftReference to new String object. Since the reference is to newly created object and not a string literal, it can be garbage collected.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top