我在面试中被问到一个问题 - 在下面的Heap中创建了多少个对象:
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个对象。
有人可以澄清在堆上创建了多少个String对象?我错过了什么吗?
答案 0 :(得分:0)
你是对的。一个String对象由"A"
创建并放入内存堆。一个字符串文字String pool
将放入String pool
。
分配将在堆中,但它仍将分别存储String文字,并使用new分别创建对象。
在早期版本的Java中,我认为最新的Java 1.6
permgen area
位于堆的PermGen space
,但在Java 1.7中更新它移动到主堆区域。早在String literals
之后,创建太多String对象总是存在风险,因为它的空间非常有限,默认大小为64 MB,用于存储类元数据,例如.class文件。创建过多的java.lang.OutOfMemory: permgen space
会导致String pool
。现在因为{{1}}被移动到更大的内存空间,所以它更加安全。
答案 1 :(得分:0)
答案是1." A"在通过存在于堆中的String Pool
运行的3行中的任何一行之前添加到堆中。前两行引用字符串池中的现有值。第三行强制在堆上创建新对象。
这是一篇很棒的文章: http://www.journaldev.com/797/what-is-java-string-pool
注意:我已在以下评论中予以纠正。 " A"在第1行运行之前,线程池中已经存在,因此第1行实际上没有添加任何内容。因此,正如您在访谈中所说,对堆的净更改为1,因为只有第3行实际上影响了堆。