Interned Strings?

Questions about YourKit Java Profiler
Post Reply
Gibson
Posts: 181
Joined: Mon Apr 11, 2005 10:38 am

Interned Strings?

Post by Gibson »

If I have a small application like this:

Code: Select all

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?
rblasch
Posts: 64
Joined: Mon Jan 10, 2005 7:13 pm

Post by rblasch »

IMHO, you can't see it because the String is stored in the constant pool, which is not part of the heap.

"Interned Strings" are something different. There's a pool which helps to make sure a string is only allocated once.

Ron
Vladimir Kondratyev
Posts: 1626
Joined: Tue Aug 10, 2004 7:52 pm

Post by Vladimir Kondratyev »

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.
Anton Katilin
Posts: 6172
Joined: Wed Aug 11, 2004 8:37 am

Post by Anton Katilin »

Hi,

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.

Best regards,
Anton
Anton Katilin
Posts: 6172
Joined: Wed Aug 11, 2004 8:37 am

Post by Anton Katilin »

Implemented in upcoming build 640.
Gibson
Posts: 181
Joined: Mon Apr 11, 2005 10:38 am

Post by Gibson »

Nice work, I just downloaded 640 and played with it a bit. Being able to view strings in the constant pool is what I was after.

As you noted, I still can't see explicitly interned strings, e.g.:

Code: Select all

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.
rblasch
Posts: 64
Joined: Mon Jan 10, 2005 7:13 pm

Post by rblasch »

That's ok, because "Hello" is gone after "s = null".

Ron
Gibson
Posts: 181
Joined: Mon Apr 11, 2005 10:38 am

Post by Gibson »

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.
rblasch
Posts: 64
Joined: Mon Jan 10, 2005 7:13 pm

Post by rblasch »

But, as Anton said, interned strings are subject to garbage collection. The string will be freed during the next collections.

The implementation can be found at
JDK 1.3.1
j2sdk1.3.1/src/share/javavm/runtime/gc.c

JDK 1.5.0
hotspot/src/share/vm/memory/symbolTable.cpp

Ron
Gibson
Posts: 181
Joined: Mon Apr 11, 2005 10:38 am

Post by Gibson »

Ah, I see I misunderstood. Thanks for clearing that up for me!
R
rblasch
Posts: 64
Joined: Mon Jan 10, 2005 7:13 pm

Post by rblasch »

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.

Code: Select all

class String {
    static Set interned = new WeakHashSet();

    String intern() {
        if (interned.contains(this)) {
            return interned.get(this);
        } else {
            interned.put(this);
            return this;
    }
}
Ron
Post Reply