当前位置: 首页 > 知识库问答 >
问题:

Java:String intern()和StringPool到底是如何工作的?

呼延运恒
2023-03-14

根据Javadoc关于字符串。实习生():

调用intern方法时,如果池中已经包含一个由equals(Object)方法确定的等于此String对象的字符串,则返回池中的字符串。否则,将此String对象添加到池中并返回对此String对象的引用。

我对此没有什么问题。

  1. 当创建一个新的字符串对象(不是使用字符串文字,而是使用new()操作符)时,如:String str=new String(“Test”)

问:我知道将在堆中创建一个新对象。但是在对象创建期间,它还会将String测试放入stringpool吗?如果是,那么为什么不直接为stringpool返回引用。如果没有,为什么不直接将字符串放入池中,因为现在StringPool已移出PermGen,并且位于常规堆空间中(即,除了堆空间限制之外,没有空间约束)。有些帖子指出,一旦创建对象,字符串就会插入池中,而有些帖子也与此相矛盾。

一旦我们调用字符串。字符串对象上的intern()(因为文字已经被插入)分配给该对象的空间会发生什么变化?它是在同一时刻回收还是等待下一个GC循环?

关于SO的另一个问题的公认答案指出,当您需要速度时,应该使用String intern,因为您可以通过引用来比较字符串(=比等于快)。

问:我知道当使用String.intern()时,它返回对StringPool中已经存在的字符串的引用。但是这需要对StringPool进行全面扫描查找,这本身可能是一个昂贵的操作。那么在字符串比较期间达到这种速度是合理的吗?如果是,为什么?

我看了以下来源:

  • JavaDoc
  • SO问题1,问题2,问题3
  • http://java-performance.info/string-intern-in-java-6-7-8/
  • 以及来自SO和外部世界的其他消息来源

共有1个答案

淳于飞鸾
2023-03-14
  1. 所有字符串文字都在编译时被截留。使用字符串文字和接受字符串的单参数构造函数有点滥用该构造函数,因此您可能会得到其中两个(但可能有一个特殊的编译器案例,我不能肯定)。从java 8开始,构造函数(对于openjdk)的实现是这样的:
public String(String original) {
    this.value = original.value;
    this.hash = original.hash;
}

所以这方面没有特殊处理。如果你知道字面意思,不要使用这个构造函数。

我不认为字符串有任何特殊的GC语义学。一旦它无法访问并被GC视为值得收集的任何其他对象,它就会被收集。

永远不要使用==来比较字符串,字符串的默认equals方法的第一步就是这样做。如果这是你的主要情况(你知道你大部分时间都在处理插入字符串),那么你只需支付一个很小的方法调用的开销,这样做以后可能会增加bug,这对于收益微乎其微的人来说风险太大了。

 类似资料:
  • 我们知道主存域很少:年轻的、终生的(旧的gen)和PermGen。 年轻领域分为伊甸园和幸存者(有两个)。 OldGen用于生存的对象。 MaxTenuringThreshold防止对象过早地被最终复制到OldGen空间。这很清楚,也很容易理解。 但是它是如何工作的呢?垃圾回收器如何处理这些在MaxTenuringThreshold之前仍然存在的对象,以何种方式?它们位于何处? 对象被复制回幸存者

  • 我正在学习Spring核心认证,我对Spring如何处理bean生命周期有一些疑问,特别是bean后处理器。 所以我有了这个模式: 我很清楚这意味着什么: 然后在bean创建阶段执行以下步骤: > 每个bean都在缺省情况下被急切地实例化(按照正确的顺序创建,并注入其依赖项)。 在依赖注入之后,每个bean都会经历一个后处理阶段,在这个阶段中可能会进行进一步的配置和初始化。 > 初始化器:如果指示

  • 这是一个简单的错误:我在对象的格式字符串中使用了而不是。但我完全困惑于我的测试结果与错误的格式字符串。 以下代码: @Jan建议依赖toString()方法可能会有问题,所以我定义了一个日期格式,以与上面相同的代码打印。下面是附加输出:

  • 我几乎理解了尾递归是如何工作的,以及它与普通递归之间的区别。我只是不明白为什么它不要求堆栈记住它的返回地址。 在尾递归函数中调用函数本身后没有什么可做的,但对我来说这没有意义。

  • 当我创建一个api并使用laravel资源时,是更好地获取完整的数据,然后选择在资源文件中发送哪些列,还是从数据库中选择数据时,确定应该选择哪些列? 1)