繁体   English   中英

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM