substring method in String class causes memory lea

2020-01-29 06:07发布

It is said that substring method in String class causes memory leak. Is it true? How? What is an alternative for it?
Especially looking for answer,
What are all other things which can causes of memory leak in java? This will help me to take care while coding.

4条回答
Viruses.
2楼-- · 2020-01-29 06:50

In past versions of the JDK, the implementation of the substring method would build a new String object keeping a reference to the whole char array, to avoid copying it. You could thus inadvertently keep a reference to a very big character array with just a one character string. Here's an example of a bug this could induce.

This method has now been changed and this "leak" doesn't exist anymore.

If you want to use an old JDK (that is older than OpenJDK 7, Update 6) and you want to have minimal strings after substring, use the constructor taking another string :

String s2 = new String(s1.substring(0,1));

As for your second question, regarding " other things which can causes of memory leak in java", it's impossible to answer in a constructive way. There aren't in java standard libs many instances of cases where you could so easily keep hidden references to objects. In the general case, pay attention to all the references you build, the most frequent problems probably arising in uncleaned collections or external resources (files, database transactions, native widgets, etc.).

查看更多
戒情不戒烟
3楼-- · 2020-01-29 06:51

The substring() method doesn't allocate a new character array for a String, but rather simply produces a String with a window onto the existing char array. This is an impementation of a flyweight pattern and was regarded as an optimisation.

So if I have a huge String (char array) and then create a substring, even if I garbage collect the original string, the original char array remains (despite the fact that you think you have a substring of, say, 2 chars). This problem is often encountered when (say) parsing a huge stream of input data (perhaps an XML file) and extracting a small amount of text via substring()

Using the seemingly redundant String(String str) constructor (a String constructor taking a String!) resolves this since it allocates a new (potentially smaller) char array, allowing the original to be garbage collected.

Note this behaviour has changed as of Java 7u6.

查看更多
叼着烟拽天下
4楼-- · 2020-01-29 06:53

In the String object, when you call substring, the value property is shared between the two strings.

So, if you get a substring from a big string and keep it for a long time, the big string won't be garbage collected. It could result in a memory leak, actually.

查看更多
Emotional °昔
5楼-- · 2020-01-29 06:55

String substring can result in retaining more memory than you might expect. As such it's not a memory leak as this memory can be recovered normally.

The simplest solution is to use a recent version of Java 7, which doesn't do this. As this is the only freely supported version from Oracle, you should consider doing this anyway.

As such it was "fixed" in Java 7 update 5. IMHO it is not so much a fix as a simplification of the implementation. Taking a copy of every substring takes much more work and is likely to consume more memory, but it does mean there is one less thing to worry about.

What are all other things which can causes of memory leak in java?

Any object can be cleaned up as such it's not possible to create a memory leak in the C/C++ sense of the term. What you can do is hold onto objects incorrectly. A common example of this is forgetting to close resources like JDBC resource. This can cause you to retain memory in ways you don't expect.

查看更多
登录 后发表回答