【问题标题】:How many String objects are created on the Heap [duplicate]在堆上创建了多少个 String 对象[重复]
【发布时间】:2015-09-25 03:19:27
【问题描述】:

我在一次采访中被问到一个问题——在下面的堆上创建了多少个对象:

String s1= "A";
String s2= "A";
String s3= new String("A");

我回答 1 - 因为只使用 new 运算符,就会创建一个字符串对象。当编译器遇到 s1 时,它会简单地在字符串字面量池上创建“A”。并且 s1 和 s2 指向文字池中的相同文字。但是面试官说这个池子在哪里,让我很困惑?

现在,在某个博客中,我读到:

“在 Java 的早期版本中,我认为 Java 1.6 之前的字符串字面量池位于堆的 permgen 区域,但在 Java 1.7 更新中它移到了主堆区域。”

所以通过这种方式,所有 3 个字符串对象都在 Heap 上创建。不是吗?

但 s1 和 s2 指向字符串字面量池中的同一个字面量(s1==s2 为真),因此遇到 s2 时不应创建单独的对象。所以以这种方式,应该只创建 2 个对象。

有人能澄清一下Heap上创建了多少String对象吗?我错过了什么吗?

【问题讨论】:

    标签: java string string-literals


    【解决方案1】:

    你是对的。一个 String 对象由String s3= new String("A"); 创建并放入内存堆。一个字符串文字"A" 将被放入String pool

    分配将在堆中,但仍将单独存储 String 字面量,并单独存储使用 new 创建的对象。

    在 Java 的早期版本中,我认为直到 Java 1.6 String pool 位于堆的 permgen area 中,但在 Java 1.7 中更新它已移至主堆区域。早些时候,因为它在PermGen space,所以创建太多 String 对象总是有风险的,因为它的空间非常有限,默认大小为 64 MB 并用于存储类元数据,例如.class 文件。创建太多String literals 会导致java.lang.OutOfMemory: permgen space。现在因为String pool 被移动到更大的内存空间,所以更加安全。

    来源:String-literal and String-object

    【讨论】:

    • 您有什么参考资料,还是我们应该相信您?
    • @JonathonReinhart 我已经更新了我的答案。请检查
    【解决方案2】:

    答案是 1。在通过堆中存在的String Pool 运行 3 行中的任何一行之前,“A”被添加到堆中。前两行引用字符串池中的现有值。第三行强制在堆上创建一个新对象。

    这是一篇很棒的文章: http://www.journaldev.com/797/what-is-java-string-pool

    注意:我在下面的评论中得到纠正。在第 1 行运行之前,线程池中已经存在“A”,因此第 1 行实际上没有添加任何内容。因此,正如您在采访中所说,堆的净变化是 1,因为只有第 3 行实际上影响了堆。

    【讨论】:

    • 是的 - 文章的第一行:“顾名思义,字符串池是存储在 Java 堆内存中的字符串池”。 2011 年 1.7 中的变化发生在堆中。
    • 第一行没有向字符串池添加任何内容。 “A”已经存在,因为类已加载。它最初是由编译器放入.class文件的字符串池中,由类加载器池化的。
    • 感谢@EJP 5. 更新答案以反映更正。应该已经去睡觉了:)
    • 明白了..!谢谢杰森 W 和@EJP !!最终计数是 1.. 很高兴知道我是对的。 :)
    • 嗨@JasonW,我已经对你的答案投了赞成票。
    猜你喜欢
    • 2014-11-26
    • 1970-01-01
    • 2018-04-28
    • 2014-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-06
    • 2012-05-13
    相关资源
    最近更新 更多