【问题标题】:does intern() method have implication on performance?intern() 方法对性能有影响吗?
【发布时间】:2019-05-07 10:14:51
【问题描述】:

我对@9​​87654322@ 方法的用处有些困惑。

这行代码可以解开我的疑惑:

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

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

【问题讨论】:

  • “我对 intern() 方法的用处有些困惑” 解决你困惑的简单方法是不要使用它。我不是在刻薄:它很少有用。
  • 你给出的例子没有用,因为String a = "abc";已经被实习了。
  • 你认为它为什么会提高性能?
  • Interning string 减少内存使用,性能可能会稍差。有关更多信息,请查看这篇文章:geeksforgeeks.org/interning-of-string。但是,我想说它几乎没有用处。
  • @parichay07 你不会这样做的。你举的例子是任何人都不应该做的。

标签: java heap-memory string-pool


【解决方案1】:

上面这行代码会创建多少个对象?

  • 字符串文字在运行时由一个String 对象表示。如果该对象尚未创建,则可能通过执行此语句来创建(惰性)。在任何一种情况下,表示文字的对象都将被实习。 (在此过程中创建的String 对象的数量是一个实现细节,取决于 Java 版本。是的,真的。)

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

  • 由于最初的String o 对象被保留,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 将自动删除在几个 GC 周期中存活的 String 对象。由于此适用于相对长寿的对象,因此这是一种更有效的去重方法。而且这个过程对应用程序是透明的!

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

【讨论】:

    【解决方案2】:

    你将有两个字符串:

    • "abc" - 字符串文字。它还将“abc”添加到字符串池中(见下文)
    • new String("abc") - 使用 new 运算符显式创建的“abc”的新副本

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

    此外,分配不会创建任何新对象。

    方法intern

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

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

    【讨论】:

      猜你喜欢
      • 2011-11-12
      • 2014-01-05
      • 1970-01-01
      • 2021-09-05
      • 1970-01-01
      • 1970-01-01
      • 2019-11-04
      • 2012-11-09
      • 1970-01-01
      相关资源
      最近更新 更多