Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/381.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么JVM不立即垃圾收集未引用的字符串对象?_Java_String_Garbage Collection_Jvm - Fatal编程技术网

Java 为什么JVM不立即垃圾收集未引用的字符串对象?

Java 为什么JVM不立即垃圾收集未引用的字符串对象?,java,string,garbage-collection,jvm,Java,String,Garbage Collection,Jvm,所以,如果我声明一个String对象str并给它赋值,然后给同一个String对象str赋值,因为String类是不可变的,一个新的String对象将在内存中创建,str现在指向这个新对象。但是,既然旧的String对象现在被none引用,为什么不能立即对其进行垃圾收集呢?我知道,如果使用相同的值创建一个新的字符串文字,则会返回相同的早期对象,但这种情况发生的可能性较小。当JVM知道糟糕的开发人员在其巨大的for循环的每次迭代中都创建3个字符串对象时,它为什么不运行GC 因为这不值得花时间。在这

所以,如果我声明一个String对象str并给它赋值,然后给同一个String对象str赋值,因为String类是不可变的,一个新的String对象将在内存中创建,str现在指向这个新对象。但是,既然旧的String对象现在被none引用,为什么不能立即对其进行垃圾收集呢?我知道,如果使用相同的值创建一个新的字符串文字,则会返回相同的早期对象,但这种情况发生的可能性较小。当JVM知道糟糕的开发人员在其巨大的for循环的每次迭代中都创建3个字符串对象时,它为什么不运行GC

因为这不值得花时间。在这个问题上,分代收集器比在分配时微管理每个字符串快得多。与复制收集器大量执行的操作相比,在管理少量内存方面会有很大的开销。

注意,自java 7以来,以下行为已发生变化,以防止出现下面描述的问题。 这个答案给出了很好的详细解释

除了Will所说的,每次创建字符串并不意味着JVM可能没有对该字符串的其他引用。这是因为字符串的实习生行为

e、 g

但是,不会在内部创建新的字符串文字。相反,“x”和“y”都引用相同的文本字符串。字符串的开始和结束索引属性 y将是0,1->指向文字->这是一个新字符串


免责声明:术语可能不完全准确

我知道如果创建了新的字符串文字,您如何创建和分配字符串对象?我的意思是说我不使用String strAllOverAgain=asd//假设asd是早期stringString foo=asd的值;foo=自闭症;不重新创建asd字符串实例。我们用的是同样的。引用asd并不能创建它,它可以是一个存在于某处的常量,可能是因为使用它的类是loadedI know。我是这个意思。字符串foo=asd;System.out.printlnfoo是+foo.hashCode;foo=def;System.out.printlnfoo是+foo.hashCode;字符串boo=asd;System.out.printlnboo为+boo.hashCode;关于如何/何时/何处创建文字:y将不会引用同一个字符串,更确切地说,它的backing char[]由x引用。至少从OracleJDK7开始就没有了。是的,这在Java7中发生了变化,我不知道。将添加注释
String x = "This is a new string"
String y = x.subString(0,1) ; //y = "T"
x = null; //discard X