我正确地实习了我的弦乐吗?

Jac*_*ine 4 java memory-management

我想确保我不打击permgen空间,所以我小心翼翼地实习我的琴弦.

这两个陈述是否相同?

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

String s2 = "hello".intern() + "world".intern();
Run Code Online (Sandbox Code Playgroud)

UPDATE

我如何构思我的问题与实际应用完全不同.这是我使用实习生的方法.

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 = ".";
Run Code Online (Sandbox Code Playgroud)

Gar*_*vis 10

我能想到的最好的建议是:不要打扰.除非你动态创建一个字符串,否则静态声明的字符串将在常量池中如何...错误,我不能想到一个原因.

我从97年开始使用Java进行编程,而且我从未实际使用过String.intern().

编辑:看到你的更新后我真的认为你不应该使用intern().您的方法看起来很正常,并且很少或没有理由使用intern().

我之所以这样做是因为它会感染优化并且可能是一个过早的优势,你是第二个猜测垃圾收集器.如果你的方法是短暂的,那么结果字符串将很快在下一个小GC中死于年轻一代,如果它不是它将在成熟一代被囚禁(因为想要一个更好的词)无论如何.

我想这是一个好主意的唯一一次,如果你花了一些时间在一个分析器上,并证明它对你的应用程序的性能有很大的影响.

  • 阅读http://kohlerm.blogspot.com/2009/01/is-javalangstringintern-really-evil.html (3认同)
  • 实习生()不是邪恶的...你只是不需要它 (3认同)
  • 我已经用Java编程了多年,只使用了intern()两次,同时对一些基于服务器的软件进行了非常彻底的性能优化,这些软件需要支持尽可能多的会话.99.99%的时间你永远不应该使用它,如果你找到一个有意义的地方,一定要考虑对你的permgen空间的影响:你只想实习小的,有限的文字集. (2认同)

Jon*_*eet 10

正如jensgram所说,这两个陈述并不相同.两条重要规则:

  • 在代码级联字符串文字与字符串常量结束,所以这两个语句完全等效(对方产生相同的字节码):

    String x = "foo" + "bar":
    String x = "foobar";
    
    Run Code Online (Sandbox Code Playgroud)
  • 字符串常量是自动实现的,您无需显式执行

现在,这集中在文字上 - 你实际上是在调用intern文字,还是你的真实用例有些不同(例如从你经常看到的数据库中获取的内部值)?如果是这样,请提供更多详细信息.

编辑:好的,根据问题编辑:这可以节省一些内存,如果你最终存储的返回值toAddress()的地方,它会坚持围绕长一段时间你同一地址多次告终.如果不是这样,那么实习可能会让事情变得更糟.我不确定被拘禁的琴弦是否永远存在,但这很有可能.

在我看来,它不太可能很好地利用实习,而且可能会使事情变得更糟.你提到试图拯救permgen空间 - 为什么你相信实习会有帮助呢?除非我错了,否则串联的字符串最终不会以permgen结尾.


Lau*_*ves 7

不会.将两个互连的字符串添加到一起并不能为您提供实习字符串.

也就是说,很少有人需要"小心翼翼地实习".除非你处理大量相同的字符串,否则它比它的价值更麻烦.

  • 再次,javac进行连接,因此"helloworld"已经被实习.使用javap -c来查看. (2认同)