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.

- 525,659
- 79
- 751
- 1,130

- 10,365
- 5
- 31
- 52
-
You're a little vague, don't you think? What makes you think this? – Jeroen Vannevel Mar 25 '13 at 10:04
-
1The way substring is implemented has been changed recently. – Thilo Mar 25 '13 at 10:04
-
1When you say "It is said that...", you should really include a reference to such a claim in your question... – Armen Tsirunyan Mar 25 '13 at 10:05
-
I see somebody voted to reopen the question. I'm not against it but I think that such a vote should be accompanied by a comment explaining why the question should be reopened. – Denys Séguret Mar 25 '13 at 10:53
-
I have voted to reopen it as I didn't get OK answer for _What are all other things which can causes of memory leak in java? This will help me to take care while coding._ From this post I understood that I should ask only one question at a time :-) – AmitG Mar 25 '13 at 10:57
-
@AmitG You can't get a constructive answer on *"What are all other things which can causes of memory leak in java? This will help me to take care while coding"*. Please have a look at the faq : SO isn't about listing all things of a kind, as this can hardly get one definitive unique answer. – Denys Séguret Mar 27 '13 at 12:05
-
Refer link http://www.programcreek.com/2013/09/the-substring-method-in-jdk-6-and-jdk-7/ – Deepak Feb 04 '16 at 05:53
4 Answers
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.).

- 1
- 1

- 372,613
- 87
- 782
- 758
-
2
-
1"Problem" is a bit harsh. The implementation has changed with 7u6, so anything before that would be "affected". – Thilo Mar 25 '13 at 10:07
-
-
2
-
Note the specification has not changed. It is technically implementation dependent (although there's not much variation in implementations). – Tom Hawtin - tackline Mar 25 '13 at 10:08
-
3One could argue that the old implementation had its advantages, too, because substring() was O(1) (not anymore), and consumed much less memory if you still needed the original String (for long Strings). – Thilo Mar 25 '13 at 10:09
-
@Thilo of course there were good reasons for the old implementations. This was after all an old trick frequently used in C. But in the age of garbage collecting, this probably caused too many bugs. – Denys Séguret Mar 25 '13 at 10:11
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.

- 268,207
- 37
- 334
- 440
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.

- 525,659
- 79
- 751
- 1,130
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.

- 1,616
- 2
- 16
- 39
-
2
-
You're right: I should have mentioned it. Thanks for the precision! – Alban Dericbourg Mar 25 '13 at 10:14