intern()方法对性能有影响吗?

时间:2019-05-07 10:14:51

标签: java heap-memory string-pool

我对intern()方法的有用性感到困惑。

这行代码可以消除我的困惑:

String a = new String("abc").intern();

以上代码行将创建多少个对象?如果它将在堆内存以及字符串池内存中创建一个对象,那么intern()方法如何提高性能?

2 个答案:

答案 0 :(得分:2)

  

以上代码行将创建多少个对象?

  • 字符串文字在运行时由一个String对象表示。如果尚未创建该对象,则可以通过执行该语句来(懒惰地)创建 。无论哪种情况,代表文字的对象都将被插入。 (此过程中创建的String对象的数量是取决于Java版本的实现细节。是的,确实如此。)

  • 每次new String(...)都会创建一个对象。

  • 由于原始String对象已被阻止,因此intern()调用将返回该对象;即表示字符串文字的String:您开始使用的文字。

因此,总而言之,您的代码可能导致直接在幕后最多创建三个对象,但是由new创建的对象在语句结尾将不可访问。

的确如此,

String a = new String("abc").intern();

String a = "abc";

给出相同的结果,new / intern序列完全浪费时间。


  

如果它将在堆内存以及字符串池内存中创建一个对象,那么intern()方法如何提高性能?

不会直接提高性能:

  • 如果您可以实习数据结构中的所有字符串,则有潜在的间接好处。然后,您可以使用==而不是equals(Object)来测试是否相等。

    但是,您需要权衡equals的成本和intern的成本,因此您需要进行一些对象比较,然后才能获得净性能。另外,如果您忘记插入其中一个字符串,则==可能会为您提供对equals的不同答案。 (这可能是一个错误!)

  • 在较早的JVM中,如果您有许多寿命长的String对象,则有潜在的间接收益。使用intern进行重复数据删除将减少长期内存使用并减少长期GC成本。

    但是,在最近的JVM中,GC将自动 去重复String个对象,这些对象可以保留几个GC周期。由于此 only 仅适用于寿命相对较长的对象,因此这是一种更有效的重复数据删除方法。而且该过程对应用程序是透明的!

简而言之,在大多数情况下,在应用程序代码中使用intern()方法没有优点和缺点。别管它。

答案 1 :(得分:1)

您将有两个字符串:

  • "abc"-字符串文字。还会在字符串池中添加“ abc”(请参阅​​下文)
  • new String("abc")-使用新运算符明确创建的“ abc”新副本

请注意,调用intern不会发生任何事情,因为自声明字符串文字以来,字符串池中已经存在字符串"abc"

该分配也不会创建任何新对象。

方法intern

  

返回字符串对象的规范表示。   最初为空的字符串池由String类私有维护。调用intern方法时,如果池已经包含等于equals(Object)方法确定的此String对象的字符串,则返回池中的字符串。否则,将此String对象添加到池中,并返回对此String对象的引用。因此,对于任何两个字符串s和t,当且仅当s.equals(t)为true时,s.intern()== t.intern()为true。   所有文字字符串和字符串值常量表达式均已插入。字符串文字是在Java™语言规范的第3.10.5节中定义的。

在这种情况下,对实习生的调用没有任何用处,因此您的性能不会得到任何提高。