Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Am I correctly interning my Strings?

I want to make sure I don't pummel the permgen space, so I'm carefully interning my strings.

Are these two statements equivalent ?

String s1 = ( "hello" + "world" ).intern(); 

String s2 = "hello".intern() + "world".intern();

UPDATE

How I framed my question was totally different from the actual application. Here's the method where I am using intern.

public String toAddress( Transport transport )
{
    Constraint.NonNullArgument.check( transport, "transport" );

    switch( transport )
    {
    case GOOGLE:
    case MSN:
        return ( transport.code() + PERIOD + _domain ).intern();
    case YAHOO:
    default:
        return _domain;
    }
}
private String _domain;  // is initialized during constructor
private static final String PERIOD = ".";
like image 615
Jacques René Mesrine Avatar asked Nov 28 '22 05:11

Jacques René Mesrine


2 Answers

The best advice I can think of is: don't bother. Statically declared String's will be in the constant pool any how so unless you are dynamically creating a String that is...errr no I can't think of a reason.

I've been programming using Java since 97 and I've never actually used String.intern().

EDIT: After seeing your update I really am of the opinion that you shouldn't be using intern(). Your method looks perfectly normal and there there is little or no reason to use intern().

My reason for this is that it is infect an optimisation and potentially a premature one at that, you are second guessing the garbage collector. If the just of you method is short lived then the resulting string will die the young generation very shortly afterwards in the next minor GC and if it isn't it'll be interned (for want of a better word) in the mature generation anyhow.

I guess the only time this could be a good idea is if you spend a bit of time with a profiler and prove that it makes a large difference to the performance of your application.

like image 90
Gareth Davis Avatar answered Dec 05 '22 16:12

Gareth Davis


As jensgram says, the two statements are not equivalent. Two important rules:

  • Concatenating string literals in code ends up with a string constant, so these two statements are exactly equivalent (they'll produce identical bytecode):

    String x = "foo" + "bar":
    String x = "foobar";
    
  • String constants are interned automatically, you don't need to do it explicitly

Now, this concentrates on literals - are you actually calling intern on literals, or is your real use case somewhat different (e.g. interning values fetched from a database which you'll see frequently)? If so, please give us more details.

EDIT: Okay, based on the question edit: this could save some memory if you end up storing the return value of toAddress() somewhere that it'll stick around for a long time and you'll end up with the same address multiple times. If those aren't the case, interning will actually probably make things worse. I don't know for sure whether interned strings stick around forever, but it's quite possible.

This looks to me like it's unlikely to be a good use of interning, and may well be making things worse instead. You mention trying to save permgen space - why do you believe interning will help there? The concatenated strings won't end up in permgen anyway, unless I'm much mistaken.

like image 20
Jon Skeet Avatar answered Dec 05 '22 16:12

Jon Skeet