||[Jan. 31st, 2006|05:22 pm]
I'm making this post mostly so I can cut-and-paste it to a mailing-list, but what the heck, maybe somebody reading this will know the answer, too.|
My game has a crash-bug. In certain circumstances (not easily reproducible, ha-ha aren't THOSE the best kinds of bugs), it will use up enough memory to exceed the default JVM heap size, and the whole thing dies with a java.lang.OutOfMemory exception.
Now, this can be pretty easily prevented by running it from the command-line with the flag "-Xmx 256M", which tells the JVM to use more memory. But the problem with that solution is that our intended distribution method for the game is for the users to download it by right-clicking on the link, and run it by double-clicking the icon. Any startup procedure more complex than that is Just Too Hard. Open up a command prompt and type things that have to be spelled correctly? No way.
I guess that means I need to get it to use less memory. Okay, run a profiler on it. Now, our game has some pretty big data objects that we send back and forth between client and server by serializing them to XML. I already knew that the serialization code (which is third-party, and which I'm not going to touch) is pretty slow. Now I'm pretty sure that it's also a memory hog. In particular, I discovered that I can hit the "garbage collect NOW" button in the profiler and the memory usage drops by HALF. And the objects that get collected appear to all be spawned by things in the serialization code.
So... I'm thinkin' that means that I want garbage-collection to run more aggressively.
If I put a "System.gc()" call in at the end of the procedure that serializes the entire gamestate to XML, that should help, right?
Any pitfalls to prompting the garbage-collector to run in the spots where I know a lot of dead objects are being created?
Or am I barking up entirely the wrong tree?
That's what I was thinking. Not hard in Windows or Unix, and I don't see a downside.
I think System.gc() is also safe, but not always reliable - it is a *suggestion* that "hey, you could run the garbage collector now if you want," but it doesn't *force* garbage collection. I have been bitten by this.
I'm almost certain ng_nighthawk's concerns are unfounded, unless I'm misreading what he's saying. gc() won't collect memory that still has pointers to it.
We can't have an installer because 90% of our target market will be playing the game on machines where they don't have permission to install anything.
However, we could probably get away with a self-executing batch file or something like that. Any suggestions on places to find patterns to follow?