tags:

views:

597

answers:

4

I have a Java application that's very String-heavy - it takes a feed of huge numbers of big, different String objects.

Do I need to worry about the String Constant Pool for memory and performance?

Is there any way to see how big the pool is at any point?

+1  A: 

I think you should profile your application, both with and without interning. You will then see exactly what the effect is.

I don't believe there is a way to see the size of the string constant pool.

Chris Jester-Young
+3  A: 

If it is a feed of objects, then they do not go into the String constant pool unless you call intern(), as far as I know. The memory consumption for interned strings is not from the Heap, but from the Perm Gen memory space, so if you intern a lot of strings the application will crash with OutOfMemory, even if there is a lot of Heap left.

So it shouldn't be a concern unless you are interning all of these strings. If it becomes a concern, it would be possible to have your own Map implementation to store these strings, so you don't use the internal mechanism.

I checked the implementation of the intern() method and it is native, so it does not seem to be straightforward to measure the memory consumption, or to see the contents of the pool.

You can use this flag to increase the PermSize if you run out of memory:

-XX:MaxPermSize=64m
Mario Ortegón
+4  A: 

As Mario said, the constant pool is only relevant to intern()ed Strings, and to Strings that are constants in java code (these are implicitly interned).

But there is one more caveat that might apply to your case: the substring()-method will share the underlying char[] with the original strings. so the pattern

  String large = ...                  // read 10k string
  String small = large.substring(...) // extrakt a few chars
  large = null;  // large String object no longer reachable,
                 // but 10k char[] still alive, as long as small lives

might cause unexpected memory usage.

mfx
Nice one, I didn't know that caveat. There is this package constructor that takes the char[] as an argument and holds the strong reference. So what to do if we really want a copy of only the substring?
Mario Ortegón
String small = new String(large.substring(...))
Dave Cheney
A: 

Not knowing exactly what the program is, I can only suggest you attempt to use the strings as a stream, and store not the string as a whole. Perhaps you need to make more abstractions for your app, and invent an intermediate representation that is more memory efficient?

Chii