hellzone hellzone - 9 months ago 27
Java Question

Why String methods like concat creates a new String Object?

Why methods like concat() returns a new String object instead of returning an object from String pool? I have found that there is a method called intern() which returns the object from String pool. I still don't understand why methods like concat() doesn't use this method when returns a new String.

String a = "test";
String b = "tes".concat("t"); //but not "tes".concat("t").intern();


public String concat(String str) {
int otherLen = str.length();
if (otherLen == 0) {
return this;
}
int len = value.length;
char buf[] = Arrays.copyOf(value, len + otherLen);
str.getChars(buf, len);
return new String(buf, true); // return new String(buf, true).intern();
}

Answer Source

You should note that calling intern() on a String doesn't prevent the original String being created. i.e. most of the short term cost has been paid and intern()ing it is likely to make matters worse in most use cases.

String.intern() is designed for String constants which are intended to be long lived. They were part of the Perm Gen (until Java 6) and were cleaned up relatively rarely. Another limitation of the String intern pool is that the bucket size didn't resize and you could get a significant hit to performance if you loaded many Strings into it. i.e. it wasn't designed for this.

In the G1 collector you have a -XX:+UseStringDeduplication This reduces String duplication or more specifically the underlying array of the String This doesn't deduplicate the actual String objects as this can have unintended side effects. Note: this deduplication only occurs when the GC runs.

why the pool would start consuming a lot of memory?

The data structure to record the String objects add memory, and is more likely to retain memory as these tend to end up in tenured space and need a major collection to clean out.

I mean all newly created String objects will refer to the object in the constant pool.

You will still create a String which is short lived. And you will use some space in the pool, so for some use cases (in fact most of them) this uses more memory and is harder to clean up.

I think we will use less memory with this way.

It can, which is why the String deduplication is a better option as it will only do the medium to long lived objects.

BTW: Obvious instead of

String b = "tes".concat("t");

you should write

String b = "tes" + "t";

as the javac compiler can combine these.