3

I read many answers but none of them really answers my question exactly.

If I've a java service running on some port and a client connects to it and calls a method like:

String data = getServiceData("clientKey");

Now my question is, will this key(clientKey) be stored in String literal pool on service side? Generally literals to be stored in constant pools are figured out at compile time but what happens to strings that are passed from outside the JVM or may be while reading a file?

Heisenberg
  • 5,514
  • 2
  • 32
  • 43

2 Answers2

3

String Object is serialized at your client side and deserialized and is kept in the Heap memory. If you want it to be stored in your String Pool memory, you should use the intern() method.

    String value;
    String data = (value =getServiceData("clientKey"))==null?null:value.intern();
Kumar Abhinav
  • 6,565
  • 2
  • 24
  • 35
  • Yes, I already know about this. I'm asking about the service side. This will make my returned key to be saved in string pool on client side. – Heisenberg Aug 07 '14 at 15:19
  • 1
    @Anshul please post the code of your client method getServiceData(String).Mostly it will be in heap memory unless you are using intern() method or using a String literal – Kumar Abhinav Aug 07 '14 at 15:21
  • You mean to say if service is getting a million requests with same API key I'll have million instances of it unless it is garbage collected? – Heisenberg Aug 07 '14 at 15:28
  • 1
    @Anshul - Yes, even if the String is interned. – Hot Licks Aug 07 '14 at 15:46
  • You should not "want to store it in string pool" most of the time. – eckes Aug 10 '14 at 01:44
2

Most methods which read strings from external sources (especially BufferedReader.getLine() or Java serialisation) will not intern the strings, so the answer is no.

However if you use third party libraries, they might do it: for example there are some XML/Dom parsers known to do that (at least for element names, less often for values). Also some high performance frameworks (servlet containers) to that for certain strings (for example HTTP header names).

But generally it is used very seldom in good(!) implementations as it is much less desirable as one might think. Don't forget: before you can intern a string it must exist as an object which needs to be collected anyway, so from the point of avoiding garbage using intern() does not help. It only might reduce the working set memory if those strings survive long time (which it is not in OLTP) and might speed up equality checks slightly. But typically this only helps if you do thousands of them on the same string object.

You can check yourself if the string is already interned (you should of course not do it in production code as it interns your string and it might not work in all implementations) with:

input == input.intern()?"yes":"no"`

And yes (as asked in a comment), having million instances of the same API key can happen with this. But don't be fooled to think this is a bad thing. Actually interning them would need to search for the value and deal with a growing string pool. This can take longer than processing (and freeing) the string. Especially when the JVM can optimize the string allocation with generational allocation and escape analysis.

BTW: Java 8u20 has a feature (-XX:+UseStringDeduplication -XX:+PrintStringDeduplicationStatistics) to detect duplicate strings in the background while doing the garbage collection in G1. It will combine those string arrays to reduce the memory consumption. (JEP192)

eckes
  • 10,103
  • 1
  • 59
  • 71
  • 1
    The check `input == input.intern()` is not reliable. If the string isn’t in the pool yet, the string will be added to the pool as that’s the actual purpose of `intern()`. One possible legal implementation is to add the very instance you are calling `intern()` on. In other words, the check might return `true` because *now* the string is indeed interned as a side effect of this test. Oh and by the way, the string deduplication feature has been added to Java 8 already… – Holger Sep 17 '15 at 12:54
  • Yes, its Java 8 I fixed the answer. I am not sure if it is legal to intern the same instance you call .intern() on, however is there any implementation which does this? – eckes Sep 21 '15 at 16:18