2015-09-25 59 views
2

有人问我在interview-问题在堆上创建了多少对象在以下创建:多少String对象都在堆

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

我回答1 - 由于与新的运营商只,创建一个字符串对象。当编译器遇到s1时,它只会在字符串文字池上创建“A”。而s1和s2指向文字池中相同的文字。但面试官说我的这个游泳池在哪里?

现在,在一定的博客,我读:

“在早期版本的Java,我想起来了,到Java 1.6字符串文字池位于堆PermGen的区域,但在Java 1.7更新其感动到主要堆区“。

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

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

难道有人能够澄清在堆堆上创建了多少个字符串对象?我错过了什么吗?

回答

0

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

这是一个伟大的写了起来: http://www.journaldev.com/797/what-is-java-string-pool

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

+1

是 - 文章的第一行:“顾名思义,String Pool是存储在Java堆内存中的字符串池”。迁移到堆的1.7中的更改发生在2011年。 –

+0

第一行没有向字符串池添加任何内容。 “A”已经存在,因为该类已加载。它最初由编译器放入.class文件的字符串池中,并由类加载器合并。 – EJP

+0

谢谢@EJP 5.更新答案以反映更正。应该已经睡了:) –

0

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

分配将在堆中,但它仍然会分别存储字符串文字和分别使用新建立的对象。

在Java的早期版本,我想起来了,到Java 1.6 String pool位于堆permgen area,但在Java 1.7更新其移动到主堆区。由于它在PermGen space之前,因为其空间非常有限,默认大小为64 MB,并且用于存储类元数据(例如, .class文件。创建太多String literals可能会导致java.lang.OutOfMemory: permgen space。现在因为String pool被移动到更大的内存空间,所以它更安全。

enter image description here

来源:String-literal and String-object

+0

你有什么参考资料吗,还是我们应该信任你? –

+0

@JonathonReinhart我已经更新了我的答案。请检查 – YoungHobbit