创建新对象并选择旧对象进行垃圾回收

时间:2017-01-21 15:50:28

标签: java string garbage-collection

在下面的代码片段中,将创建新的String对象来存储修改后的新字符串,因为Strings在java中是不可变的。但我不确定哪一个会创建新对象,哪一个会被标记为垃圾回收?

String s1 = "It";
String s2 = "was";
String s3 = s1+" "+s2;
s2+=" roses";
s3 = s3+s2+" roses all the way";
System.out.println(s3);

2 个答案:

答案 0 :(得分:0)

这取决于您的代码段的范围。

如果所有代码都在一个方法中,那么所有代码​​在执行后都将处于垃圾状态。

垃圾收集器处理对象的引用计数。

例如,您在方法中声明一个新的引用String s1并分配给某些东西。然后执行方法并在完成时没有更多的引用。所以,去垃圾。

答案 1 :(得分:0)

这是一个简短的基本解释,实际行为可能因编译器和JVM的使用而有所不同。此外,还有很多文章可以深入讨论这个主题,并可以提供更详细的解释。

这些文字将放在JVM的字符串池中,永远不会被GC。 (即它们将在JVM期间存在于内存中。

"It", "was", " ", " roses", " roses all the way"

然后,就字符串引用而言,它取决于变量的范围。我将假设这个答案的本地方法级别:

String s1 = "It"; // a reference will be created on the stack 

String s2 = "was"; // a reference will be created on the stack 

String s3 = s1+" "+s2; // a reference will be created on the stack for s3, and then two temp objects will be created in memory, one for s1+" ", one for concatenating the result with +s2.  (this operation can vary greatly based on how compiler optimizes),  the first one will become eligible for GC immediately.

s2+=" roses"; // same as above.

s3 = s3+s2+" roses all the way"; // same as above but the object s3 was pointing to will become eligible for GC immediately.

System.out.println(s3); // no memory allocation.

当方法结束时,s1,s2和s3引用将从堆栈中清除,并且任何指向的剩余对象都符合GC的条件。

希望这会有所帮助,请记住这是一个非常基本的解释,我建议阅读这个主题,因为它的实际行为可能会有很大差异,具体取决于编译器决定如何优化。 (例如,编译器可能会看到所有这些临时引用和连接都不需要并丢弃它们)

注意:由于您要连接以创建字符串,因此您可能需要考虑可以帮助优化的StringBuffer或StringBuilder之类的Mutable替代方法。