||[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?
Since you get to cut-and-paste to a mailing list, the least I can do is cut-and-paste my mailing-list response back into LJ ;).
I suppose it's possible your JVM would die with an OutOfMemory without first trying to garbage-collect all that it could, but my guess is that you've got an honest-to-god loop somewhere that's actively pointing to all that memory. If so, GCing won't help
fix your bug.
As for launching by double-clicking, Java really does fulfill the promise of "write once, break everywhere." Do you expect all your users to have the JVM installed already? The right version of it? With all the classes you need?
Here's an article that might help:http://www.excelsior-usa.com/articles/java-to-exe.html
If you don't mind doing machine-specific downloads, you might also try a batch file or launcher.
So far, the answer seems to be that yes, actually, nearly all of our users have a compatible JVM already installed, and those that don't (typically mac and linux users) are sophisticated enough to install it themselves.
But that article is really useful! Thanks!
Suggestions on how to do a simple batch file / launcher? I'm not at all opposed to machine-specific downloads. They're so common that everyone knows how to deal, and it shouldn't be a big deal on our end to generate them...
I haven't really used Windows since, well since it was called DOS, but can't you just put the java command you want in a file called "double-click-on-me.bat" and then put it in a ZIP file along with the JAR file?
I think the launcher approach lets you make it just a single file rather than JAR + batch file, but I've never done that in Windows-land.
Yeah, but there's enough setup steps already that I really want to make it invisible if I possibly can. "Download this file, then unzip it, then double-click this other file" is guaranteed to have more people get lost than "download this file and double-click it", sadly.
The article you linked to had some suggestions about launchers; I'm going to look into those.