Java 堆上创建了多少个字符串对象
在一次采访中,我被问到一个问题——堆上创建了多少个对象,如下所示:Java 堆上创建了多少个字符串对象,java,string,string-literals,Java,String,String Literals,在一次采访中,我被问到一个问题——堆上创建了多少个对象,如下所示: String s1= "A"; String s2= "A"; String s3= new String("A"); 我回答了1-因为只使用新操作符,就创建了一个string对象。当编译器遇到s1时,它只需在字符串文本池上创建“A”。s1和s2指向文本池中的同一个文本。但面试官说这个人才库在哪里,这让我很困惑 现在,在某个博客上,我读到: “在Java的早期版本中,我认为Java 1.6的字符串文字池位于堆的permgen区
String s1= "A";
String s2= "A";
String s3= new String("A");
我回答了1-因为只使用新操作符,就创建了一个string对象。当编译器遇到s1时,它只需在字符串文本池上创建“A”。s1和s2指向文本池中的同一个文本。但面试官说这个人才库在哪里,这让我很困惑
现在,在某个博客上,我读到:
“在Java的早期版本中,我认为Java 1.6的字符串文字池位于堆的permgen区域,但在Java 1.7中,它的更新被移动到主堆区域。”
这样,所有3个字符串对象都在堆上创建。不是吗
但是s1和s2指向字符串文本池中的相同文本(s1==s2为true),因此在遇到s2时不应创建单独的对象。因此,以这种方式,只应创建2个对象
有人能澄清一下在堆上创建了多少字符串对象吗?我遗漏了什么吗?你是对的。一个字符串对象由
strings3=新字符串(“A”)创建代码>并放入内存堆。一个字符串文本“A”
将被放入字符串池
分配将在堆中,但仍将分别存储字符串文本和使用new创建的对象
在Java的早期版本中,我认为Java 1.6String pool
位于堆的permgen区域
,但在Java 1.7中更新了它的主堆区域。早些时候,由于它位于PermGen空间
,因此创建太多字符串对象总是有风险的,因为它的空间非常有限,默认大小为64 MB,用于存储类元数据,例如类文件。创建过多的字符串文本
可能会导致java.lang.OutOfMemory:permgen space
。现在,因为字符串池
被移动到了更大的内存空间,所以更加安全
资料来源:答案是1。在通过堆中存在的字符串池运行3行中的任何一行之前,将“A”添加到堆中。前两行引用字符串池中的现有值。第三行强制在堆上创建新对象
下面是一篇很棒的评论:
注意:我对下面的评论进行了更正。在第1行运行之前,线程池中已经存在“A”,因此实际上没有在第1行中添加任何内容。因此,正如您在采访中所说,堆的净变化为1,因为只有第3行实际影响堆。您有任何参考资料,或者我们应该信任您吗?@JonathonReinhart我已经更新了我的答案。请选择Yes——文章的第一行:“顾名思义,字符串池是存储在Java堆内存中的字符串池”。1.7中移动到堆的更改发生在2011年。第一行没有向字符串池添加任何内容。“A”已经存在,因为类已加载。它最初由编译器放入.class文件的字符串池中,然后由类加载器合并。谢谢@EJP 5。更新答案以反映更正。应该已经睡觉了:)明白了。。!谢谢Jason W和@EJP!!最终计数为1。。很高兴知道我是对的。:)嗨@JasonW,我已经投票支持你的答案了。