简体   繁体   English

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

[英]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. 我想确保我不打击permgen空间,所以我小心翼翼地实习我的琴弦。

Are these two statements equivalent ? 这两个陈述是否相同?

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

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

UPDATE 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 = ".";

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() . 我从97年开始使用Java进行编程,而且我从未实际使用过String.intern()

EDIT: After seeing your update I really am of the opinion that you shouldn't be using intern(). 编辑:看到你的更新后我真的认为你不应该使用intern()。 Your method looks perfectly normal and there there is little or no reason to use intern(). 您的方法看起来很正常,并且很少或没有理由使用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. 如果你的方法是短暂的,那么结果字符串将很快在下一个小GC中死于年轻一代,如果它不是它将在成熟一代被囚禁(因为想要一个更好的词)无论如何。

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

As jensgram says, the two statements are not equivalent. 正如jensgram所说,这两个陈述并不相同。 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 (eg interning values fetched from a database which you'll see frequently)? 现在,这集中在文字上 - 你实际上是在文字上调用intern ,还是你真正的用例有些不同(例如从你经常看到的数据库中获取的实际值)? 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. 编辑:好的,基于问题编辑:这可以节省一些内存, 如果你最终存储toAddress()的返回值,它会坚持很长一段时间你会多次使用相同的地址。 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? 你提到试图挽救permgen空间 - 为什么你相信实习会有帮助呢? The concatenated strings won't end up in permgen anyway, unless I'm much mistaken. 除非我错了,否则串联的字符串最终不会以permgen结尾。

No. Adding two interned strings together does not give you an interned string. 不会。将两个互连的字符串添加到一起并不能为您提供实习字符串。

That said, it's pretty rare that one needs to "carefully intern one's strings". 也就是说,很少有人需要“小心翼翼地实习”。 Unless you're dealing with huge numbers of identical strings, it's more trouble than it's worth. 除非你处理大量相同的字符串,否则它比它的价值更麻烦。

I would say no. 我会说不。 s1 adds "helloworld" to the pool, whereas s2 is made up of the two pooled strings "hello" and "world". s1将“helloworld”添加到池中,而s2由两个池化的字符串“hello”和“world”组成。

More info will help us to understand your query... Anyway... 更多信息将帮助我们理解您的查询......无论如何......

If you manually want to intern for HelloWorld then go with first statement as in second statement you interning hello and world separately. 如果您手动想要为HelloWorld实习,那么请使用第一个语句,如第二个语句中分别实现hello和world。 Two statements are not identical at all. 两个陈述完全不相同。

You might want to have some form of proof (via profiling perhaps) that you are "pummelling the permgen space" before you write all your code like that. 在编写所有代码之前,您可能希望获得某种形式的证明(通过概要分析),即“扼杀permgen空间”。

Otherwise you may just be doing "premature optimisation" which is generally frowned upon. 否则你可能只是做“过早优化”,这通常是不赞成的。 See http://en.wikipedia.org/wiki/Optimization_(computer_science)#When_to_optimize for more details on why this may be a bad thing. 请参阅http://en.wikipedia.org/wiki/Optimization_(computer_science)#When_to_optimize ,了解有关为什么这可能是一件坏事的更多细节。

In many cases, "carefully interning" your strings gives you nothing but some time wasted. 在许多情况下,“仔细实习”你的琴弦只会浪费你一些时间。 Consider the following case: 考虑以下情况:

void foobar(int x) {
  String s1 = someMethod(x).intern();
  ...
  ...
}

So s1 is interned, no (heap) space wasted? 所以s1被实习,没有浪费(堆)空间? Wrong! 错误! Most likely, the intermediary result of someMethod(x) still exists somewhere on the heap and needs to be garbage collected. 最有可能的是,someMethod(x)的中间结果仍然存在于堆上的某个地方,需要进行垃圾回收。 That's because someMethod() somehow constructed the string, and (unless it returns a literal) it did that on the heap. 那是因为someMethod()以某种方式构造了字符串,并且(除非它返回一个文字)它在堆上做了。 But then... better look up what the permgen space is used for. 但那么......更好地查看permgen空间的用途。 It's used for metadata about classes and (ooops) the String.intern table. 它用于关于类的元数据和(ooops)String.intern表。 By interning all your strings, you are doing exactly what you wanted to avoid: Pummel the permgen space. 通过实习你的所有琴弦,你正在做你想要避免的事:Pummel permgen空间。

More information here: http://www.thesorensens.org/2006/09/09/java-permgen-space-stringintern-xml-parsing/ 更多信息请访问: http//www.thesorensens.org/2006/09/09/java-permgen-space-stringintern-xml-parsing/

你正在使用的字符串数量对JVM的Permananent Generation 没有影响,因为我们还在讨论一个

interning strings is basically a memory leak waiting to happen :( 实习字符串基本上是等待发生的内存泄漏:(

Unless you have a very, very good reason[1] don't do it, but leave it to the JVM. 除非你有一个非常非常好的理由[1]不这样做,但是把它留给JVM。

[1] As in, "Dear Boss, Please don't fire me. I have this profiling data to support my decision to use intern" :) [1]如同,“亲爱的老板,请不要解雇我。我有这个分析数据来支持我决定使用实习生”:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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