4
\$\begingroup\$

I've been working on a game in Java that, for this post's sake, looks like Terraria and has random world generation. I've been using Vectors to contain my tile/block objects, but recently due to the nature of the calculations I perform on them fairly often, I've switched my system to 2D arrays, using 'chunks.'

Each 2D array (chunk) of blocks is 256x256. That's a lot of data, and considering that's only for one chunk (the player will probably have 30-50 chunks generated by the end of the game), the amount of live objects increases quickly.

Today I started getting lag spikes in-game when I generated about 15 chunks or so. After a few print statements, it was clear that the spikes were pretty inconsistent, and although I have no knowledge of the Java garbage collector, I can only assume it is the culprit.

I read that the more live objects you have (the ones that are still referenced somewhere), the more the GC will lag when it does its thing. Plus, all these blocks are taking up huge blocks of memory which is causing the GC to start in the first place.

I have tried saving the unloaded chunks to a file for later use, but as you can imagine, saving that much data isn't exactly efficient. I'm stumped here.

Does anyone have any suggestions on how to reduce the amount of live objects in-game?

\$\endgroup\$
  • 2
    \$\begingroup\$ Have you looked into object pools? \$\endgroup\$ – MichaelHouse Sep 19 '14 at 4:18
  • \$\begingroup\$ Have you tried to look in your VM using jconsole? jconsole provides you with informations about memory allocation and runtime... \$\endgroup\$ – Uwe Plonus Sep 19 '14 at 6:01
  • \$\begingroup\$ @Byte56 I just did, but I don't really see how they can solve my problem. Wouldn't I still have to store all the tiles' data somewhere? \$\endgroup\$ – TheBeocro Sep 19 '14 at 10:27
2
\$\begingroup\$

Before anything, I'd look for a heap profiler and make sure it's the GC that's causing problems. However, if you find that it is indeed the number of objects you have in memory, you've already come up with the basic solution; page your chunks out to disk once in a while and only keep nearby ones in memory.

But, as you've seen, there are problems with the approach, namely slowness. My first recommendation here is the same as above; use a profiler and check what's actually taking so long. A few general tips:

  1. You can spread out the disk writes over multiple update steps, or compress the data before writing it (although, that might be slower than the alternative, depending on your CPU/disk).

  2. You may also check to make sure the format (XML, json) you're writing to isn't introducing unnecessary overhead. I haven't done serialization in a while, but from brief researchObjectOutputStream outputs to a binary format which might be faster than human-readable. The exact format of the data is difficult to recommend without knowing what tile data you need. Here is a reference for Minecraft's chunk format.

  3. The GC may be trying to cleanup all your unloaded chunks. This is where Byte56's comment comes in. If you use an object pool to manage all your tile objects, then instead of leaving all those orphans for the GC to destroy, you'll reuse them in other chunks that get paged in later.

Again, you should prove your suspicions with a profiler before taking any action. Don't waste any time optimizing that you could be using to finish your game. I've used VisualVM before, and found it useful.

\$\endgroup\$
  • \$\begingroup\$ Thanks for the detailed answer! I will use a profiler, though that chunk format link introduced something I hadn't thought of before: I don't even have to save the chunks, I only have to save the changes made to them. That will actually probably solve my problem by itself, though like I said, I'll still check out VisualVM just because I've heard it's useful. \$\endgroup\$ – TheBeocro Sep 19 '14 at 19:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.