Java 字符串池-字符串对象-垃圾回收
在以下情况下,垃圾收集是如何工作的。考虑下面的代码Java 字符串池-字符串对象-垃圾回收,java,string,garbage-collection,Java,String,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 referenc
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
如果使用newstring()
String s1 = new String("abc");
那么结果会是什么呢
还有什么工具,通过我们可以监控垃圾收集,因为在第一种情况下,GC会收集哪些对象
String s1 = "abc"
您的字符串将进入JVM维护的字符串池,并且永远不会被垃圾收集
但在第二种情况下
String s1 = new String("abc");
一般规则适用,字符串对象的作用域一结束就会被垃圾回收。在第一种情况下
String s1 = "abc"
您的字符串将进入JVM维护的字符串池,并且永远不会被垃圾收集
但在第二种情况下
String s1 = new String("abc");
一般规则适用,字符串对象的作用域一结束就会被垃圾回收。string s1=“abc”//s1指向“abc”
这里,“abc”将被添加到字符串常量池中,并且通常不会被GCed。任何字符串文字(在双引号内)通常不会被GCed
字符串s1=新字符串(“abc”)
上面的一行创建了两个字符串。“abc”将被添加到字符串常量池中(假设它还不存在),另一个值为“abc”的字符串将被添加到堆中。堆上存在的字符串对象一旦变得不可访问(即,没有对它的引用),就可以对其进行gcd)String s1=“abc”//s1指向“abc”
这里,“abc”将被添加到字符串常量池中,并且通常不会被GCed。任何字符串文字(在双引号内)通常不会被GCed
字符串s1=新字符串(“abc”)
上面的一行创建了两个字符串。“abc”将被添加到字符串常量池中(假设它还不存在),另一个值为“abc”的字符串将被添加到堆中。堆上的字符串对象一旦变得不可访问(即,没有对它的引用),就可以对其进行gcd)您可以使用它,它由Oracle本身提供,用于监视包括内存在内的许多事情
另一个小窍门以获得洞察力。考虑下面的代码。
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
String a=“abc”
String b=“abc”
如果我们执行比较引用的a==b
,它实际上将返回true,因为Java知道abc是相同的,并且它将被引用到字符串池中的相同内存
因此,当没有对字符串的引用时,它是GC完成其工作的线索。您可以使用它,它由Oracle本身提供,用于监视包括内存在内的许多事情
另一个小窍门以获得洞察力。考虑下面的代码。
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
String a=“abc”
String b=“abc”
如果我们执行比较引用的a==b
,它实际上将返回true,因为Java知道abc是相同的,并且它将被引用到字符串池中的相同内存
因此,当没有对字符串的引用时,它是GC完成其工作的线索。对于垃圾收集监视,您可以参考以下内容
有关垃圾收集监控,您可以参考以下内容
嗯,事情并不像听起来那么简单。答案取决于您使用的Java版本。 所有可以在编译时解析的字符串文字(如示例中的文字)都来自字符串常量池,基本上是在JVM开始时创建的哈希表,并在类加载时更新 如果您使用的是Java6,那么这个字符串常量池是PermGen的一部分,PermGen是堆外的一个空间,但由Java进程管理。就像Heap一样,GC在这个区域中不会被触发,直到它完全被触发。除非你要处理数百万个类或者你的PermGen大小很小,否则这个区域不会很快填满,GC也不会经常出现。所以在回答你的问题时,即使删除了对“abc”的所有引用,它也不会被GC’ed,直到永久发电机充满为止 从Java7开始,字符串常量池也是堆的一部分,因此您的对象分配率可能会影响GCs的频率,并且“abc”可能比Java6中的更快被清除 没有专门的工具来检查哪些对象是GC对象,但是我们有一些很酷的工具,这些工具与标准JDK一起提供,可以帮助我们更好地理解GC和内存消耗,并对其进行调优 VisualVM-有一个名为VisualGC的插件-通过它,您可以了解GC的发展趋势 Java任务控制中的FlightRecorder显示了比VisualVM更多的关于GC和内存消耗的数据
如果您需要更多信息,请查看此信息:)这并不像听起来那么简单。答案取决于您使用的Java版本。 所有可以在编译时解析的字符串文字(如示例中的文字)都来自字符串常量池,基本上是在JVM开始时创建的哈希表,并在类加载时更新 如果您使用的是Java6,那么这个字符串常量池是PermGen的一部分,PermGen是堆外的一个空间,但由Java进程管理。就像Heap一样,GC在这个区域中不会被触发,直到它完全被触发。除非你要处理数百万个类或者你的PermGen大小很小,否则这个区域不会很快填满,GC也不会经常出现。所以在回答你的问题时,即使删除了对“abc”的所有引用,它也不会被GC’ed,直到永久发电机充满为止 从Java7开始,字符串常量池也是堆的一部分,因此您的对象分配率可能会影响GCs的频率,并且“abc”可能比Java6中的更快被清除 没有专门的工具来检查哪些对象是GC对象,但是我们有一些很酷的工具,这些工具与标准JDK一起提供,可以帮助我们更好地理解GC和内存消耗,并对其进行调优