Or "How I just saved myself 3 meg of precious Android heap memory".
I always glazed over whenever I came across how Strings are implemented in higher level languages. The most important advice I ever came across concerning them was "use a library that does all that string stuff for you". Of course I can make reasonable assumptions about how Java does strings:
1. There's a char buffer somewhere in there storing sequences of raw characters
2. It probably does something clever with them along the lines of the same way I do textures
So what happened? A loader parses an entire
object file into a string, then passes a tokenized element of that string into an object as the object's name. It all seemed fine till I ran the
Eclipse Memory Analysis Tool, when I found at the top of my memory usage hitlist a bit more than 3 megabytes of char data. As in, a couple of raw char[]. Full of, guess what? My entire object file.
"What's happened here?", I thought, stroking my chin. A closer look at my object in the debugger (a Submesh) revealed that sure enough, its name (supposed to be something like "grp 1"), which is a String, has the entire object file in its buffer. The String object stores an offset and length into the character buffer. The garbage collector looks at the 3 meg buffer and says "well, this Submesh object here still has a reference to this sequence of data, so I can't delete it!".
The fix is trivial: construct a new string from the passed in string, which makes a new buffer and frees up the old one for the GC's unreferenced memory hit squad.
I thought I'd post this because without running the MAT I never would have known I was leaking 3 megs of memory. It's worth checking.