Sponsors



Go Back   Zune Boards > Zune Discussions > Zune Games > Development Discussions

New Member?



 
Register Zunecentive FAQ Members List Calendar Search Today's Posts Mark Forums Read

Development Discussions All developers who are coding games may stop by here for any help, suggestions, and everything development related.

Reply
 
LinkBack Thread Tools
Old 06-02-2008, 07:57 PM   #1 (permalink)
Zewbie
 
Join Date: Jun 2008
Posts: 6
Reputation: 12
$zB: 6
Donate
Default C# Garbage Collection Problems

I'm programming a ribbon trail. The moving point that has the ribbon trail has a RibbonTrail object, which is contains a List of Particle objects. Each Particle has a Vector2 for position, and a float for its lifespan. In the Update method, I call the UpdateLifespan method of RibbonTrail, which decreases the lifespan of each particle by 1. If any of the particle objects has a lifespan <= 0, I remove them from the List.

I experience extreme frame rate slow downs after a minute of having the ribbon trail, but it plays fine for the first 20 seconds. Since the Particles are unnamed, and once I remove them from the List they have no references, why aren't they being deleted by the Garbage Collector? And, how can I ensure that the then useless Particle object gets deleted?



ujax is offline   Reply With Quote
Remove Advertisements Sponsored Links
Advertisement
 
Old 06-02-2008, 10:35 PM   #2 (permalink)
zB Programmer
Jr. Member
 
DiNoGames's Avatar
 
Join Date: May 2008
Location: Bremen, germany
Posts: 347
Reputation: 101
Send a message via Skype™ to DiNoGames
$zB: 257
Donate
Default

You should set the maximum number of particles to a fixed value, prepare the list with "blank particles", for example mark them as unused (a bool is good enough here).

Now, when you add a particle, mark the first unused as used and set its values...

When a particle dies, just mark it as unused again.

In your game loop, just update and draw the particles marked as used.

Always use this list and do not add new particles or delete them. Just use the prepared ones (they stay in memory and do not bother the garbage colletor, which has the same problems like the XBox GC (no real generation system for objects)).

I guess this way it should run at a decent speed over time and not only for 20 secs.

EDIT:
And as a second note, try to acoid things like:


Position = new Vector2(newPosX, newPosY);

(which will create a new Vector2 object for every particle every frame. -> load for the garbage collector)

You should rather say:
Position.X = bla bla
Position.Y = bla bla
(which uses the already created Vector2 object -> no load for the garbage collector)
__________________

To view links or images in signatures your post count must be 0 or greater. You currently have 0 posts.


To view links or images in signatures your post count must be 0 or greater. You currently have 0 posts.

Last edited by DiNoGames : 06-02-2008 at 10:41 PM.






DiNoGames is offline   Reply With Quote
Old 06-02-2008, 11:58 PM   #3 (permalink)
zB Programmer
Experienced Zuner
 
Join Date: Nov 2007
Posts: 112
Reputation: 38
$zB: 100
Donate
Default

hmm to be honest, it doesn't sound like a problem with Garbage Collection(I use TONS of particle generators in my game, Squadron Z and have no problems with it) since it wouldn't cause slow frame rates, it would make your program run out of memory and crash. Sounds more like you aren't actually removing the particles from the list(or not all of them at least). Try running it under a debugger and after it really starts slowing down put a breakpoint somewhere and see how many particles you have. I'll bet it's a lot more than you think
__________________
-Mark
Check out my new game, "Squadron Z":
To view links or images in signatures your post count must be 0 or greater. You currently have 0 posts.


Check out my version of pong with multiplayer:
To view links or images in signatures your post count must be 0 or greater. You currently have 0 posts.



MarcusMaximus is offline   Reply With Quote
Old 06-03-2008, 12:46 AM   #4 (permalink)
Jr. Member
 
SimReality's Avatar
 
Join Date: May 2008
Posts: 410
Reputation: 60
$zB: 353
Donate
Default

I think there's some confusion in here. First of all, is your Particle type a class or a struct? If it's a struct, then it gets allocated on the stack (not the heap) and therefore the garbage collector doesn't do anything with that memory. It is just allocated and released as needed. If it is a class, then yes, the garbage collector will clean those up after all references are gone.

Generally an issue from the garbage collector is a quick stutter in frame rate due to the garbage collector taking up some time. If garbage truly is the issue here, then your goal should be to prevent the garbage collector from running.

That said that might not even be the issue. How many particles do you have in there? How are you updating them? The Zune isn't the most powerful machine and if you have enough stuff in there, you might just see a slowdown because of that.



SimReality is offline   Reply With Quote
Old 06-03-2008, 12:48 AM   #5 (permalink)
Jr. Member
 
SimReality's Avatar
 
Join Date: May 2008
Posts: 410
Reputation: 60
$zB: 353
Donate
Default

Quote:
Originally Posted by DiNoGames View Post
And as a second note, try to acoid things like:


Position = new Vector2(newPosX, newPosY);

(which will create a new Vector2 object for every particle every frame. -> load for the garbage collector)
That's incorrect. Vector2 is a value type and therefore is allocated on the stack; not the heap. Creating any value type will not create garbage.



SimReality is offline   Reply With Quote
Old 06-03-2008, 03:21 AM   #6 (permalink)
Jr. Zuner
 
Join Date: May 2008
Posts: 33
Reputation: 15
$zB: 33
Donate
Default

Nick is, of course, right about Vector2 being a value type so doesn't create garbage.

My take on the GC is to *never* allocate objects (that is reference types, not vaue types) when the game is running. This includes arrays. Even if you create a new array of a value type (e.g. Vector2), the array itself is a reference type and creates garbage.

My Manic Miner Zune game allocates all the level data, content, everything as the game loads. Appreciate this may not always be possible (Manic Miner is a simple 2D game).

Another thing to watch out for is foreach. Sometimes it generates garbage, sometimes it doesn't. My approach is to *never* use foreach. There's always an alternative to foreach, using something like:

for (int i = 0; i < whatever.count; i++)
{
SomeItem item = whatever[i];

// Work with item
}

My first XNA game ran like a dog. Adopting a few design principles at the start means things run fine.

Hope this helps.

- Gunston.

Last edited by Gunston : 06-03-2008 at 03:25 AM.



Gunston is offline   Reply With Quote
Old 06-03-2008, 03:39 AM   #7 (permalink)
zB Programmer
Jr. Member
 
DiNoGames's Avatar
 
Join Date: May 2008
Location: Bremen, germany
Posts: 347
Reputation: 101
Send a message via Skype™ to DiNoGames
$zB: 257
Donate
Default

Quote:
Originally Posted by SimReality View Post
That's incorrect. Vector2 is a value type and therefore is allocated on the stack; not the heap. Creating any value type will not create garbage.
Ok, thanks for the tip... Always appreciate learning new things
__________________

To view links or images in signatures your post count must be 0 or greater. You currently have 0 posts.


To view links or images in signatures your post count must be 0 or greater. You currently have 0 posts.






DiNoGames is offline   Reply With Quote
Old 06-03-2008, 06:38 AM   #8 (permalink)
Jr. Member
 
SimReality's Avatar
 
Join Date: May 2008
Posts: 410
Reputation: 60
$zB: 353
Donate
Default

Quote:
Originally Posted by Gunston View Post
My take on the GC is to *never* allocate objects (that is reference types, not vaue types) when the game is running.
Technically the allocation of new objects is perfectly fine. It's only the releasing of objects that gets you. So you are totally fine to create thousands of new reference types while the game is running, but if you lose all those references, you'll get a garbage collection. A subtle difference, but worth noting.

Quote:
Another thing to watch out for is foreach. Sometimes it generates garbage, sometimes it doesn't. My approach is to *never* use foreach. There's always an alternative to foreach, using something like:

for (int i = 0; i < whatever.count; i++)
{
SomeItem item = whatever[i];

// Work with item
}
Most collections will not allocate using foreach. I almost always use foreach and I rarely see garbage issues from it. It's also worth noting, though, that where foreach may or may not allocate, the standard for loop with the indexing is likely going to be just a tad slower because indexing into the array performs bounds checking each time through your loop whereas the enumerator used by the foreach loop doesn't have that issue. So there is a possibility of a foreach loop running faster than a standard for loop. Also the foreach loop is generally easier to read, so you are trading a minimal (and only potential) garbage issue for a harder to read and potentially (though only slightly) slower method.

My personal recommendation is to always favor foreach unless you have proven (using profiling) that your loop is generating garbage.



SimReality is offline   Reply With Quote
Reply


Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On
Forum Jump


Register and remove this ad

All times are GMT -8. The time now is 06:49 AM.

 
Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO 3.2.0 RC8
vB Ad Management by =RedTyger=
(C) ZuneBoards 2006-2007
Copyright © 2006 - 2008 Zune Boards | About Zune Boards | Legal | A member of the Crowdgather Forum Community