我正在搜索由java中的subString()方法引起的内存泄漏.我在互联网上阅读了一些文章,并获得了一些知识,但我最终有点困惑.一篇文章提到了"String类中的substring方法,调用String(int offset,int count,char value [])构造函数来创建新的String对象.这里有趣的是,value [],它是用于相同的字符数组代表原始字符串".这对我来说很清楚.
它还提到"如果原始字符串非常长,并且具有1GB的数组,无论子字符串有多小,它将保存1GB数组. 这也将阻止原始字符串被垃圾收集,以防万一有任何实时参考 ".
这篇文章的链接在这里 { http://javarevisited.blogspot.sg/2011/10/how-substring-in-java-works.html }
我不明白这.请有人解释一下,如果它没有任何实时参考,它如何阻止原始字符串被垃圾收集?
根据我的一点理解,在java中任何没有直接或间接引用的对象都有资格收集垃圾收集器.如果subString方法使用相同的字符数组来表示原始字符串,那么原始字符串如何保持不被垃圾回收?
同样我想知道内存泄漏是由于使用相同的字符数组来表示原始字符串引起的,因为新字符串{subString方法返回的字符串}与原始字符串相比会非常少,或者因为原始字符串仍然是住没有被垃圾收集?
请有人帮我澄清一下
当您在Java中分配任何内容时,在这种情况下为a String,只要您仍然可以访问它,它就会保留在内存中.如果你写
String s = "blah";
Run Code Online (Sandbox Code Playgroud)
然后s是一个参考到String.只要至少有一个引用String,那么JVM知道它需要在内存中保留.一旦没有更多引用,JVM就可以清理它并在需要时回收内存.
如果你写
String s = "myverylongstring...somemore...someotherstuff";
Run Code Online (Sandbox Code Playgroud)
然后你已经耗尽了相当多的记忆.在内部,这将表示为char[]包含您的所有字符String,并在边缘附加一些额外的gubbins以允许您使用StringAPI 访问它.
现在,如果你再写,会发生什么
s = s.substring(20,30);
Run Code Online (Sandbox Code Playgroud)
所以s现在只是部分原件的参考String?JVM可以通过两种方式处理它.一种是将整体保留char[]在内存中,但只需改变char[]它准备好让您访问的位.另一种是将相关位复制char[]到一个新数组中,然后去除对旧数组的所有引用.
第一种方法很快,因为它不需要任何复制.但是如果你现在只想要你的一小部分String,那么整个大部分String都无法完全清理,因为它的整个char[]仍然在内存中使用.只使用其中一部分的事实意味着它的所有内存都不能被回收.
第二种方法较慢,因为它需要复制操作.但它确实意味着之前的内容String可以完全清理,因为旧char[]的不再被使用了.
Java 曾经遵循第一种方法,但在最近(Java 7以后),它已经转向使用第二种方法.因此,内存泄漏曾经是substring()调用的问题,但不再是.
| 归档时间: |
|
| 查看次数: |
753 次 |
| 最近记录: |