public class StringTest {
public static void main (String[] args) throws Exception {
String s = "Hello";
System.out.println ("String = " + System.identityHashCode (s));
s = null;
new Controller ().captureMemorySnapshot ();
s = "Hello";
System.out.println ("String = " + System.identityHashCode (s));
}
}
then the string "Hello" is created (and interned) but not visible in the memory snapshot (perhaps because it is no longer reachable?). However, we know that it is still using memory since when we resurrect it in the next line, it's the same object. Is there any way to see objects that are in the intern pool?
AFAIK, all string literals are indeed interned; and constant pool (at least class file has such entry) doesn't contains references to any real objects. It contains just values, i.e. UTF-8 bytes of strings.
We'll investigate the possibility to access pool of interned strings.
We'll try to provide references from class to its resolved constant pool entries (i.e. string literals?) in the next build in JVMTI version of agent. But I don't promise it will appear with 100% probability.
Regarding interned strings, just for a clarification. Strictly speaking, the interned strings are not exactly the same as strings in constant pool. Yes, string literals go to the constant pool, and get interned when instantiated. But each string can also be explicitly interned (String.intern()), and I do not know the way to see all interned strings. But it's not a problem, because I believe GC is also applicable here: if interned string, a string literal, is referenced only from constant pool of class, it will live until the class is unloaded; if explicitly interned string is not referenced, it can be collected.
import com.yourkit.api.Controller;
public class InternTest {
private static String s;
public static void main (String[] args) throws Exception {
s = "Hello World".substring (0, 5);
s = s.intern ();
s = null;
new Controller ().captureMemorySnapshot ();
}
}
Searching for "Hello" I only find "Hello World".
I'm not sure how much I actually care though, since I never explicitly intern strings.
That's my point, though - since "Hello" has been interned (and it's not part of the class's constant pool) it's taking up memory somewhere but I can't see it.
Just in case anyone is curious. Here's a Java pseudo-code of what happens during intern. This applies to JVM 1.3.1, JVM 1.5.0 looks slightly different, but the idea is the same.