I’m tracking down a memory leak at the moment and just came across this really interesting article on how Strings are implemented in a number of different JVM’s. I haven’t come across this before, but its sure nice to know about… Scary stuff.
http://eyalsch.wordpress.com/2009/10/27/stringleaks/
TL;DR: The backing char arrays of Strings are held on to and can’t be garbage collected, so…
Do this:
[java]
String string = “abcdefghijklmnopqrstuvqxyz”;
string = new String(string.substring(2, 5));
[/java]
Instead of this:
[java]
String string = “abcdefghijklmnopqrstuvqxyz”;
string = string.substring(2, 5);
[/java]
Hmm. Nice to know this. Btw I have to assume that I hate the first way xD. I neer instantiate Boolean or Strings at all xD.
Yeah I always think it looks funny seeing new String() but stress testing some server software and seeing your heap usage skyrocket is worse IMO
In that example, it should make no difference as the strings are literals and will be interned anyway as part of the Class literals.
It’s when you get a string from another source (say reading a file) and then do a substring() on it that you worry about it keeping that whole file around in memory.
@pspeed said:In that example, it should make no difference as the strings are literals and will be interned anyway as part of the Class literals.
Yeah for that example it wouldn't really matter.. I didn't even think of that, I just consciously decided not to write out all of the code to open and read a file from memory :)
Sure. I just wanted to point out that in your example you actually waste memory instead of save it.
Interesting indeed, its like doing a substring() on a string causes the returned string to reference the main string and thus it will only be released when the substring object is released. Easy to remember but you really gotta know this one ^^
Many times, this memory sharing is actually a really good thing… and it makes substring a nearly free op.
Also if you have string and want all substrings taht ar possible the additional memory cost is quite low. I agree however, that if the original string is rather large, or only a very small part of it is needed the new String approach should be used. (I think about xml processing and Nodenames for example here ^^, btw how is the ogre loader written as we speak of it?)
I’ve came across this bug last year, as my software I work with cuting string, puting strings inside another, replacing etc. and found this annoying bug, that until today wasn’t fixed.
Its not a bug, its a feature ^^ It saves you from stuffing new objects in the heap all the time.
Yeah, but a feature that causes memory leak for me sounds like a bug.
@shirkit said:
Yeah, but a feature that causes memory leak for me sounds like a bug.
By that logic any language without automatic garbage collection should be killed off... oO?
I consider it annoying as I spent about 2 hours to discover this thing. So, for me, it’s annoying
@shirkit said:
I consider it annoying as I spent about 2 hours to discover this thing. So, for me, it's annoying
Fair enough :)
Never got a chance to think about things like this, kind of scary (agreed ! ) …
One thought: We really should have a specific sub-forum for : Low level - Java and something like Shader C…
@shirkit said:
Yeah, but a feature that causes memory leak for me sounds like a bug.
Its not a leak per se, any object that references another object keeps that other object in memory, you just need to know thats the case. Same thing can happen in any API really..
Yes, but I could never imagine that substrings suffer from this, as I String doesn’t keep references to their ancestors, so actually, this shouldn’t happen, agreed?
@shirkit said:
Yes, but I could never imagine that substrings suffer from this, as I String doesn't keep references to their ancestors, so actually, this shouldn't happen, agreed?
xD The point of this whole discussion is that a string created using otherstring.substring() _does_ keep a reference to the original ^^ So no, not agreed ;)
Hell it does stores a reference to the original. Well, I don’t agree with that anyway, but it’s their implementation, not mine.