Jump to content
  • Advertisement
Sign in to follow this  
chapter78

[.net] C# / Mono + memory concerns

This topic is 3497 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey guys, I have recently moved my C++ game engine project over to C# and Mono in order to get some quick prototyping done and to learn more about C# as a language. I still aim to complete my C++ project but it is easier to test things out quickly in a .NET environment. I have a written a function that uses Tao.PhysFs to load files from an archive, and it maps them into a MemoryStream object. I can then use this object to manipulate the files in various ways. Currently, I'm using it only to create a Bitmap texture for font rendering. I would like someone to check over this function for consistency as I'm concerned about memory usage/leakage - does the MemoryStream object (and therefore the loaded file) get garbage collected once the object has gone out of scope? For my bitmap texture its not much of a concern since this is used consistently during the engine's execution. I'm more concerned about smaller files I might load for quick reference, are they going to linger around in the memory long after they were used? The function can be seen here: http://gist.github.com/50606 (Feel free to modify it if you can explain the reasons for change). Thanks in advance, James

Share this post


Link to post
Share on other sites
Advertisement
Just make sure you call ms.Dispose() when you are done with the MemoryStream and you will be fine.

There are two strategies to ensure high GC performance:
1. Go crazy with allocations, but only during "dead" time (startup, level loading) - avoid per-frame allocations like the devil.

2. Allocate things freely, but make sure to keep the heap simple (e.g. by allocating large arrays of objects, instead of every object on its own).

Strategy #1 allows you to create as complex a heap as you like. Strategy #2 allows GC cycles to complete quickly (simple heap == only gen-0 collections).

Unfortunately, you cannot mix and match strategies.

Edit: Use the disposable pattern whenever possible!

using (MemoryStream ms = new MemoryStream(...))
{
// Do something
}



This will ensure "ms" will be collected in the very next gen-0 GC cycle. If you don't use the pattern and you don't call Dispose(), ms will be promoted to a gen-1 object - not good!

Edit 2: Mono doesn't use a generational GC yet, but it will soon.

Share this post


Link to post
Share on other sites
Thanks for your reply. Using Dispose() has given me the peace of mind that I needed and your advice on allocation is most useful. I'm coming over from a C/C++ background and so I feel a little uneasy by not paying much attention to allocation and memory management.

I should try and worry less, I'm only using C# for prototyping things - but it is nice to know you are being efficient in the process!

Thanks!

Share this post


Link to post
Share on other sites
Quote:
Original post by Fiddler
1. Go crazy with allocations, but only during "dead" time (startup, level loading) - avoid per-frame allocations like the devil.
You may want to invoke GC.Collect at the end of each of these 'dead' times, to force the garbage collector to run.

Share this post


Link to post
Share on other sites
Quote:
Original post by swiftcoder
Quote:
Original post by Fiddler
1. Go crazy with allocations, but only during "dead" time (startup, level loading) - avoid per-frame allocations like the devil.
You may want to invoke GC.Collect at the end of each of these 'dead' times, to force the garbage collector to run.


Essentially, all of my engine subsystems have an Init() routine which identify these 'dead' times (before the actual gameplay starts). I'm now performing a GC.Collect() at the end of each of these and performance hit seems to be minimal.

Memory used before collection: 1150976
Memory used after full collection: 1126400

I will perform the same cleanup on level change or gameplay stopping (returning to the menu, for instance).

Thanks for your advice.


Share this post


Link to post
Share on other sites
Just for your information, the actual memory contained in the MemoryStream does not get dumped when you call Dispose on it. You'll have to wait until the GC gets around to cleaning up the bytes.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!