对Garbage Collection
在以下情况下的工作方式感到困惑。考虑下面的代码。
String s1 = "abc"; // s1 points to "abc"
String s2 = s1; // s2 points to "abc"
String s3 = "abc1"; // s3 points to "abc1"
s1 = s3; // s1 points to "abc1"
s2 = null; // s2 reference is removed, "abc" is no longer referenced now
在此之后,"abc"
将有资格获得GC
。
如果上面的例子相同,如果我使用new String()
String s1 = new String("abc");
现在会有什么结果。
还有任何工具,通过我们可以监视垃圾收集,因为GC收集了对象
答案 0 :(得分:3)
在第一种情况下
String s1 = "abc"
你的字符串将进入由JVM维护的字符串池中,并且永远不会被垃圾收集。
然而在第二种情况下
String s1 = new String("abc");
通用规则适用,并且您的字符串对象将在其范围结束后立即收集垃圾。
答案 1 :(得分:2)
您可以使用Oracle自身提供的Visual VM来监控许多内容,包括内存。
获得洞察力的另一个小黑客。考虑下面的代码。
String a = "abc"
String b = "abc"
如果我们做a==b
比较引用,它实际上将返回true,因为Java知道abc是相同的,它将被引用到String池中的相同内存。
因此,当没有对字符串的引用时,它是GC完成工作的线索。
答案 2 :(得分:2)
答案 3 :(得分:1)
String s1 = "abc"; // s1 points to "abc"
这里,“abc”将添加到字符串常量池中,并且通常不会被GCed。任何字符串文字(在双引号内)通常都不会被GCed。
String s1 = new String(“abc”);
以上行创建了2个字符串。 “abc”将被添加到String常量池中(假设它已经不存在),并且另一个值为“abc”的String将在堆上。存在于堆上的String对象一旦变为 unreachable 就可以被GC(即,没有对它的引用)
答案 4 :(得分:0)
嗯,它并不像听起来那么简单。答案取决于您正在使用的Java版本。 可以在编译时解析的所有字符串文字(如示例中的那些)都来自字符串常量池,基本上是在JVM开头创建的HashTable,并在加载类时更新。
如果您正在使用Java 6,那么此字符串常量池是PermGen的一部分,PermGen是堆外部的空间,但由java进程管理。就像Heap一样,GC在这个地区不会被触发,直到它满了。除非你处理数百万个课程或者你的PermGen规模非常小,否则这个地区不会很快填满,GC也不会经常出现。所以回答你的问题,即使在删除所有对" abc"的引用之后,它也不会成为GC,直到PermGen填满。
从Java7开始,字符串常量池也是Heap的一部分,因此您的对象分配率可能会影响GC的频率和" abc"可能会比在Java6中更早清除。
没有特定的工具来检查哪些对象是GC,但我们有一些标准JDK附带的很酷的工具,这将有助于我们更好地理解GC和内存消耗并进行调整< / p>
VisualVM - 有一个名为VisualGC的插件 - 通过这个你可以了解GC中的趋势
Java Mission Control中的FlightRecorder 显示有关GC和内存消耗的更多数据,而不是VisualVM
如果您需要更多信息,请查看此link:)