Game jerking...memory problems perhaps?

Started by
6 comments, last by richardawusi 12 years, 11 months ago
Hi All,

I've developed a Tower Defence style game in XNA 3.1, mostly vector graphics based. I've used quite a bit of HLSL to do some glow effects, etc. The game looks great (if I may say so myself) but I have a little problem that's threatening to de-thrown everything.

After about an hour, maybe hour and a half of game play, the game starts jerking. After jerking for about 20 to 60 seconds, it begins to run smoothly again....until the next jerk! I can fill the entire game with towers bombarding enemies with bullets, rockets, laser beams, etc, and it renders perfectly fine. But after sometime, it jerks. This leads me to believe that the jerk is not caused by the number of objects which are rendered but rather a memory problem.

I have made numerous optimizations to the game which has seen memory usage decrease from 200MB after 30 mins of gameplay, to about 120MB after an hour and half of gameplay! Some changes I made was to move pretty much all variable declarations out of method bodies to be member variables of classes, since the garbage collector apparently can't clean up native memory usage. I changed all foreach loops in the game to for statements, since a foreach uses 3 integers and 2 lists in the background, whereas the for statement uses just 2 integers and 1 list. I even tried forcing garbage collection after every 30 seconds, but, as we all probably know, wasn't particularly wise :-) I went through my code to ensure I was reusing sprites when they've been destroyed, reuse particle systems, etc. After having faced over 1000 enemies, my enemy list sits at around 30, showing the reuse of enemies working fine. It's the same with the particle systems.

After all these optimizations, the game still jerks after prolonged gameplay and I've pretty much ran out of ideas as to what may be wrong. From the look of things, it appears the memory being used by my game gets fragmented and needs to be reordered, and thus, the jerky behavior. I also noticed that once I change game states, that is, I move from the running game to the menu page (which are two different objects in terms of classes), and return to the game, all's good again! Is there a specific way in XNA to either request lots of memory upfront or is there a way of managing memory such that it doesn't get fragmented or whatever...something like the 'delete' keyword in C++?

Any help will be greatly appreciated
Advertisement
I doubt if this is memory. Most of the memory used by your objects should be on the GPU, and once it gets there it stays there. You're also not using a particularly huge amount of memory (you weren't even before you did your reworking).

What I think this is is either a timer issue (you may be using a low resolution timer, or have integer overflow happening) or accumulated floating point precision loss. The latter can especially happen if you're adding a delta to a running total each frame; fp precision errors will mount up and after a while will be quite noticeably bad.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

I recently had a similar issue, which resulted from the timing calculations returning a negative value. A simple check to see if the delta time was negative solved the issue, though it wasn't exactly a perfect solution.

Saving the world, one semi-colon at a time.

Thanks for the responses

So this may be a possible timing issue or a floating point issue. I don't have control over the timer within XNA since it sets up everything for me in the background...or do I? So if it's a timing issue, how can I resolve this? MajorTom, how did you check if the delta was negative and what exactly does that mean? How is that even possible?

mhagain, assuming this is a floating point problem (which it might be since I use floating points just about everywhere), how can I resolve this?

After doing some timings on the update and draw methods, I found that the update runs at a near constant 60 updates per second, whereas the draw method gradually decreases from 60 right down about 2 draws per second. From the look of it, the update and the draw don't appear to run on the same thread. Can this still be a timing issue (possibly so) or a floating problem (how so if the update runs fine but the draw doesn't)?

So this may be a possible timing issue or a floating point issue. I don't have control over the timer within XNA since it sets up everything for me in the background...or do I? So if it's a timing issue, how can I resolve this? MajorTom, how did you check if the delta was negative and what exactly does that mean? How is that even possible?


From what I believe, if the timing functionality is derived from calls to QueryPerformanceFrequency() then QueryPerformanceCounter() it's likely that on multi-core CPU's these can return misleading results. The thread is potentially swapped between the cores at random times depending on certain architecures. Sometimes, as the frequency is slightly different on the different cores, this technique can yield negative values for delta time. In my timer class, I just check if it's lower than zero, if it is, I'll use the delta time for the last frame. This may not be the issue however, it's more likely to be something else.

Saving the world, one semi-colon at a time.

So I've been doing some googling and got an insight into how the XNA game loop works. It explained why the update runs at a consistent 60 fps, whilst the draw method gradually drops. I did some timings and noticed that the update methods takes a millisecond or so to update all sprites in the game, even when I have almost 100 towers bombarding enemies. But the draw method on the other hand starts to run into the hundreds of milliseconds per frame. This leads me to think there are too many sprites active. However, if I pause the game for a certain amount of time and unpause it, the rendering goes right up to 50 fps. But once again, after a while, it drops. I think I have a memory leak somewhere but I can't seem to spot it. Anyone have any ideas as to what the problem areas are in XNA that I should be investigating? Perhaps something to do with the drawing of primitives in XNA perhaps?
Might be a memory leak, might just be the fact that you're not resetting your sprite count back to 0 at the start of each frame. Check the params to your draw calls (and number of draw calls) and see if they're going up to extremely high numbers at the point in time when framerates plunge.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.


Might be a memory leak, might just be the fact that you're not resetting your sprite count back to 0 at the start of each frame.


I don't understand what you mean by resetting my sprite count back to zero. Can you please explain that a little more


Check the params to your draw calls (and number of draw calls) and see if they're going up to extremely high numbers at the point in time when framerates plunge.


Once again, I don't understand what you mean. The only params passed into my draw calls, where relevant, is a single SpriteBatch object for the drawing. Also, my draw calls will increase as the number of sprites in the game increases, i.e. more towers are added, more particles to draw, etc. But as that increases, the call to the draw method from XNA itself decreases. Understandably so due to its design when FixedTimeStep is not being used.

This topic is closed to new replies.

Advertisement