Java的String.split方法是否存在内存泄漏?

9

6
我意识到英语可能不是你的母语,但这个问题没有意义。请给我们一些背景信息。 - Christoffer Hammarström
我不认为这些常用的方法存在内存泄漏问题,因为从早期版本的Java就已经存在了。但是如果你发现了内存泄漏,请提供一些信息。 - Erhan Bagdemir
1
你能给我们提供你所提到的已知解决方法的链接吗? - jabal
1
以下是我从某个用户那里看到的评论:我也会在JavaDocs中提及这个问题。我遇到了类似的问题,但是是在使用String.split时而不是String.substring,它们的工作方式相同(分割块引用原始字符串的存储),我花了一些时间才找出问题所在。 - Avinash
1
Java 为了快速创建字符串而优化了子字符串/拆分,如果原始字符串需要大量内存,则必须使用通过 new String(...) 获得的副本。Java 无法为您执行此操作,因为正确的行为取决于您如何使用字符串。 - josefx
1个回答

11

更新: 从1.7.0_06版本开始,行为已更改: 请参阅此文章: Java 1.7.0_06中对String内部表示所做的更改 at java-performance.info.


正如@finnw所指出的那样,当使用String.substring时确实存在一种潜在的内存泄漏。原因是String.substring只返回给定字符串的一部分视图,即底层字符串仍保留在内存中

要强制创建一个与源字符串无关的新字符串,您必须使用new关键字。例如,您必须执行以下操作:

String[] parts = orig.split(";");
//String mySubstring = parts[i];               // keeps orig from being GC'd
String mySubstring = new String(parts[i]);     // creates a new string.
或者,更直接一些。
String mySubstring = new String(orig.split(";")[i]);

我必须说,这种行为对我来说似乎是"不必要的"。它应该可以使用弱引用或其他技术来解决。(特别是考虑到 String 已经是 Java 语言规范中的一个特殊类了。)


谢谢,但是使用split有什么问题吗? - Avinash
不需要。如果您使用“new String(...)”分离要保留的字符串,那么一切都应该没问题。 - aioobe
1
我想弱引用没有被使用的原因是它们对于垃圾回收器来说处理起来很昂贵。这是一种不幸的情况,通常是重要优化的一种情况,有时却相反。 - Stephen C
没错。不过,我仍然感到惊讶的是他们还没有通过其他方式解决这个问题,例如,如果需要的话,使用JVM内部黑科技。(反正字符串本来就已经是JLS的一部分了)。 - aioobe
@aioobe - 1) 这个内部黑客会使用什么技术?2) 虽然字符串在JLS中有特殊的地位,但我相信在最近的HotSpot JVM中,它们几乎完全是用Java实现的(我想String.intern是唯一的例外)。 - Stephen C
我想一个人也必须为split做出例外。当然,这是否是一个好主意还有待商榷。 - aioobe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接