Jump to content
Xtreme .Net Talk

Recommended Posts

Posted

I know that by looking in the taskmanager under processes you can find out how much memory your program is consuming.

 

So I suppose there is an easy way of finding out how much memory a process is using. Let�s say I have a wasteful program that destroys a lot of memory hungry objects but I don�t want to the garbage collection every cycle.

 

Is there any way to get the amount of memory my program is consuming with all destroyed object and without the destroyed objects? This would allow me to figure out when to collect my garbage.

 

A VB.net example would be much appreciated but a C example might just be as usable.

 

Anyways if you already know how to get the current memory usage I�d be glad to have it.

 

Thanks

  • Administrators
Posted

You may find some of the things mentioned in this thread useful.

Do be aware that unless you really have a requirement for managing your memory it is probably not worth the effort. Rarely is manually calling the GC beneficial, and even when it is you may find that just closing / disposing of objects in a timely fashion is a better choice.

MS has invested a lot of time and effort in the GC and forcing it to collect will often upset it - the GC will self tune over the duration of your app's execution and calling Collect can cause objects to stay in memory longer than if you left it to do it's work.

Posting Guidelines FAQ Post Formatting

 

Intellectuals solve problems; geniuses prevent them.

-- Albert Einstein

Posted
MS has invested a lot of time and effort in the GC and forcing it to collect will often upset it - the GC will self tune over the duration of your app's execution and calling Collect can cause objects to stay in memory longer than if you left it to do it's work.

Longer? How is that possible? Maybe if you do something else while you're calling Collect that prevents something from being collected that otherwise would've, that can happen, but just from calling it yourself? If you call Collect yourself, you're forcing a collection, which can hurt performance, but I can't see it making objects sit in memory longer..

Posted (edited)

Odd, but it can.

 

It has to do with the Generation of your Objects.

 

When a GC.Collect() call occurs (usually because the Heap has been exhausted) the GC will release the unreachable objects and then compact/move the rest of them. (There are some exceptions for locked objects and larger objects that are never moved.)

 

It then increments the Generation of the surviving objects. All objects start at generation 0, meaning they have "survived" zero GC.Collect() calls. Once a GC.Collect() has occured, the survivors all get incremented by 1. So all Objects that had a 0 now have a 1. If you survive a 2nd GC.Collect() call, then you're bumped up to 2. That's the limit though, generatiion '2' objects don't get incremented -- 2 is the highest that it goes.

 

The point of all this is that there are different types of objects. Generally there are larger resource objects, often Singletons, that are held in memory for the duration of your Application. These are typically opened when your Application begins and then close when your Application ends. It's too expensive (slow to open/close) so you keep it open. Or it's an object maintaining your entire internal data structure -- it's critical to your App and so it stays "alive" for the duration of your Application.

 

But then there are relatively small "throw away" objects. String objects, for example, are created and thrown away like popcorn in a typical application. A few strings like the Login Name might be held, but if any parsing or string manipulation is involved, you are likely creating and destroying a fair volume of Strings. This would be true of a number of minor objects of your Apps own creation as well.

 

So when a GC.Collect() call does occur, the "Major Objects" will survive, because a reference is held, but most of the "Minor Objects" are likely collectable. What happens after a couple of GC.Collect's is that the Major Objects will quickly graduate to level 2.

 

Now the GC.Collect() mechanism is efficient in the sense that it typically will not check all generations for collection. Something that has survived to Generation 2 is likely to survive to Generation 5 or even 17! (Which is why they stop the counting at 2.) So the Garbage Collector knows that checking the Generation 2 guys is not a very high probability undertaking. So it usually only checks the Generation 0 objects for collection. Sometimes the Level 1 and mostly not the Level 2.

 

So, here's the upshot of forcing a call to GC.Collect():

 

Let's say that you pre-maturely call GC.Collect(). You may have a number of "Minor Objects" that currently have references holding them, but probably would not survive much longer. But if you impatiently call GC.Collect() -- especially if you do it twice -- then you could artificially promote these objects to Generation 2. Now that they are Generation 2 they are likely to persist for a very long time...

 

... unless you call GC.Collect() again! Fixing a bad habit with another bad habit! You're now forced into the need to manage this process "manually" in a vain attempt to be "efficient".

 

This whole scenario is a bit of a stretch, but you get the idea...

 

The only time I find the GC.Collect() call to be legitimate (other than in time testing situations) is when releasing unmanaged resources. Some COM ActiveX Servers such as MS Excel just hang. :( Using Marshal.ReleaseComObject() is supposed to be the mechanism to release this, but as a practical matter it is all but impossible to use it correctly. I find that a call to GC.Collect() tends to be the magic bullet 99% of the tme, and is less brutal than resorting to something like Process.Kill().

 

Well, there you go, hopefully this is what PlausiblyDamp had in mind... Otherwise I've just wasted a lot of bandwidth! :)

Edited by Mike_R

Posting Guidelines

 

Avatar by Lebb

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...