[英]Am I correctly interning my Strings?
我想确保我不打击permgen空间,所以我小心翼翼地实习我的琴弦。
这两个陈述是否相同?
String s1 = ( "hello" + "world" ).intern();
String s2 = "hello".intern() + "world".intern();
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 = ".";
我能想到的最好的建议是:不要打扰。 除非你动态创建一个字符串,否则静态声明的字符串将在常量池中如何...错误,我不能想到一个原因。
我从97年开始使用Java进行编程,而且我从未实际使用过String.intern()
。
编辑:看到你的更新后我真的认为你不应该使用intern()。 您的方法看起来很正常,并且很少或没有理由使用intern()。
我之所以这样做是因为它会感染优化并且可能是一个过早的优势,你是第二个猜测垃圾收集器。 如果你的方法是短暂的,那么结果字符串将很快在下一个小GC中死于年轻一代,如果它不是它将在成熟一代被囚禁(因为想要一个更好的词)无论如何。
我想这是一个好主意的唯一一次,如果你花了一些时间在一个分析器上,并证明它对你的应用程序的性能有很大的影响。
正如jensgram所说,这两个陈述并不相同。 两条重要规则:
在代码级联字符串文字与字符串常量结束,所以这两个语句是完全等价的(它们会产生相同的字节码):
String x = "foo" + "bar": String x = "foobar";
字符串常量是自动实现的,您无需显式执行
现在,这集中在文字上 - 你实际上是在文字上调用intern
,还是你真正的用例有些不同(例如从你经常看到的数据库中获取的实际值)? 如果是这样,请提供更多详细信息。
编辑:好的,基于问题编辑:这可以节省一些内存, 如果你最终存储toAddress()
的返回值,它会坚持很长一段时间,你会多次使用相同的地址。 如果不是这样,那么实习可能会让事情变得更糟。 我不确定被拘禁的琴弦是否永远存在,但这很有可能。
在我看来,它不太可能很好地利用实习,而且可能会让事情变得更糟。 你提到试图挽救permgen空间 - 为什么你相信实习会有帮助呢? 除非我错了,否则串联的字符串最终不会以permgen结尾。
不会。将两个互连的字符串添加到一起并不能为您提供实习字符串。
也就是说,很少有人需要“小心翼翼地实习”。 除非你处理大量相同的字符串,否则它比它的价值更麻烦。
我会说不。 s1
将“helloworld”添加到池中,而s2
由两个池化的字符串“hello”和“world”组成。
更多信息将帮助我们理解您的查询......无论如何......
如果您手动想要为HelloWorld实习,那么请使用第一个语句,如第二个语句中分别实现hello和world。 两个陈述完全不相同。
在编写所有代码之前,您可能希望获得某种形式的证明(通过概要分析),即“扼杀permgen空间”。
否则你可能只是做“过早优化”,这通常是不赞成的。 请参阅http://en.wikipedia.org/wiki/Optimization_(computer_science)#When_to_optimize ,了解有关为什么这可能是一件坏事的更多细节。
在许多情况下,“仔细实习”你的琴弦只会浪费你一些时间。 考虑以下情况:
void foobar(int x) {
String s1 = someMethod(x).intern();
...
...
}
所以s1被实习,没有浪费(堆)空间? 错误! 最有可能的是,someMethod(x)的中间结果仍然存在于堆上的某个地方,需要进行垃圾回收。 那是因为someMethod()以某种方式构造了字符串,并且(除非它返回一个文字)它在堆上做了。 但那么......更好地查看permgen空间的用途。 它用于关于类的元数据和(ooops)String.intern表。 通过实习你的所有琴弦,你正在做你想要避免的事:Pummel permgen空间。
更多信息请访问: http : //www.thesorensens.org/2006/09/09/java-permgen-space-stringintern-xml-parsing/
你正在使用的字符串数量对JVM的Permananent Generation 没有影响,因为我们还在讨论一个类 。
实习字符串基本上是等待发生的内存泄漏:(
除非你有一个非常非常好的理由[1]不这样做,但是把它留给JVM。
[1]如同,“亲爱的老板,请不要解雇我。我有这个分析数据来支持我决定使用实习生”:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.