0
votes

I am currently working on a 2D Game that uses LWJGL, but I have stumbled across some serious performance issues. When I render more than ~100 sprites, the window freezes for a very small amount of time. I did some tests and I found out the following:

  • The problem occurs with both Vsync enabled or disabled
  • The problem occurs even if I cap the frames at 60
  • The program is not just rendering less frames for a short time, the Rendering seems to actually pause
  • There are no other operations like Matrix-Calculations that slow down the program
  • I already have implemented batch rendering, but it does not seem to improve the performance
  • The frequency of the freezes increases with the amount of Sprites
  • My Graphics Card driver is up to date
  • The problem occurs although the framerate seems to be quite acceptable, with 100 rendered sprites at the same time, I have ~1500 fps, with 1000 sprites ~200 fps

I use a very basic shader, the transformation matrices are passed to the shader via uniform variables each rendering call (Once per sprite per frame). The size of the CPU/GPU bus shouldn't be an issue.

I have found a very similar issue here, but none of the suggested solutions work for me.

This is my first question here, please let me know if I am missing some important information.

1
This may be due to garbage collection cycles. Start the JVM with -verbose:gc or use a memory profiler to get information about garbage collections happening and their pause times.Kai Burjack
@httpdigest Thank you for your answer, the garbage Collection actually is the Problem. When I run System.gc() every update, the freezes don't happen anymore, but the Framerate is significantly lower since the gc Needs like 0.005 secs every update. What might be the Problem here? How can I find out which objects keep filling the heap?user12678368
Use a memory profiler to identiy excessive object allocations in your hot path ("hot path" = call tree that is called the most frequent times every frame).Kai Burjack

1 Answers

0
votes

It's probably GC.

Java is sadly not the best language for games thanks to GC and lack of any structures that can be allocated at stack, from languages similar to Java - c# is often better choice thanks to much more tools to control memory, like stack alloc and just structures in general. So when writing game in languages with GC you should make sure your game loop does not allocate too many objects, in many cases in other languages people often try to go for 0 or near 0 allocations in loop.
You can create objects pools for your entities/sprites, so you don't allocate new ones, just re-use existing ones.

And if it's simple 2d game, then probably just avoiding allocating objects when there is no need to should be enough (like passing just two ints instead of object holding location on 2d map).

And you should use profiler to confirm what changes are worth it.
There are also more tricky solutions, like using off heap manually allocated memory to store some data without object overhead, but I don't think simple game will need such solutions. Just typical game-dev solutions like pooling and avoiding not needed objects should be enough.