The new face of the GC in Whidbey... I'm not sure this is a pretty face...

Brad Abrams commented several months ago about some changes in the GC that allows you to tune your application for GC collection when working with unmanaged objects.  The two concepts he talks about are a small managed object that is hiding a much larger unmanaged object in the back-end.  This would allow the memory to hang around based on the smaller size of the managed object without the GC realizing the true size of the object in question.  The second concept is that of unmanaged handles and their limited availability.  The GC can be tuned to collect more often when the number of allocated handles passes a collection threshhold and it becomes more aggressive as the maximum threshhold is approached.  For the complete article check out, http://blogs.msdn.com/brada/archive/2003/12/12/50948.aspx.

Now, I'm a day late and a dollar short to get my questions answered on the original post I'm sure.  However, I have some major issues with the patterns discussed in the article as do some of the other people commenting on the new APIs.  One individual seems to think that apps could adversely affect the GC by artificially increasing the GC pressure of certain objects.  This is definitely a valid concern.  Another individual talks about the possibility of balanced calls to Add/Remove when setting pressure.  What does happen when you add 5 megs to the pressure pool and then forget to unset it?  Does it stick around?

I'm more worried that these methods are general.  The GC doesn't know that my object is the one consuming the memory per-say.  It simply knows there is an additional 5 megs that is being used and that if it collects it might get that memory back.  I've asked the question if a this pointer is being assigned under the scenes on the blog, but I don't think it is.  I've also asked that once the object is finalized and removed from the GC, if the pressure will be removed as well in the case I forget my call to RemoveMemoryPressure.  While the article shows the call being placed in the Finalizer, I think it is more likely that it will be placed within the Dispose() pattern implementation, since you'd want to relax the GC pressure as soon as the unmanaged memory is released.

Onto the HandleCollector.  Is it just me or is this really just a helper library for classes I've already had to write when working with unmanaged resources that have limits.  This special handle collector counts the number of times Add/Remove is called and assumes that each one matches the creation and disposal of an unmanaged handle somewhere.  I'm assuming that when making calls to Add/Remove decisions are made as to whether or not a collection should occur in order to reclaim some of the unmanaged handles.  Note this really only happens if your code is lazy and you don't explicitly Dispose() your managed objects and force the release of the unmanaged handles, so for library programmers this might be a god-send.  Then again library programmers have already written their own handle pools to ensure enough handles are available for their systems to run.  Unless there is some mystical GC tuning happening behind the scenes, or unless you can attach the type of the object you'd want to collect to this new HandleCollector so that the GC only tries to collect objects that would contain an actual handle, then I don't think this is going to be very useful either.

I'd really love to see some powerful memory management tools being added to my toolbox.  Being a developer that lives and breathes plug-in systems, I'm awaiting the day that I can limit the amount of memory consumed by plug-ins in my system or at least spy on them to see which ones are being naughty (within managed code mind you).  It'd also be nice to have something like a GC.AvailableForGC(WeakReference) call.  That would make that HandleCollector pretty bitchin right.  You could loop through all of your object references, figure out only those that are available for GC, then GC.Collect(WeakReference).  Talk about some powerful stuff.

Now I know this breaks some of the .NET paradigm of not having to worry about memory, but so does tuning metrics for forcing the GC to collect more often.  The more often the GC collects the more of a performance hit your application is going to suffer.  I'd rather be in control of collecting just the objects I know are sparsely available, than having to tune my handle collector for 6 hours, trying to find out which values for initial and max threshhold are going to make the GC collect when I need it, but not so much that it affects the performance of my application.

Published Saturday, March 20, 2004 7:36 PM by Justin Rogers

Comments

Sunday, March 21, 2004 10:24 PM by TrackBack

# Take Outs for 21 March 2004.

Take Outs for 21 March 2004.
Monday, March 22, 2004 1:25 PM by Kit George [Microsoft]

# re: The new face of the GC in Whidbey... I'm not sure this is a pretty face...

Justin, I thougt I would respond to some of your queries here.

I did want to confirm that the added pressure affects everything in Gen-Zero, so it is not tied to your instance per-se. The GC simply alters its collection strategy for all Gen-Zero items as a result of the added pressure, it does not keep a close eye on one particular item.

As for your concern about what happens if you forget to remove the pressure: I have to stress, DON'T forget. We do not try to remove the pressure if you have forgotten. Therefore there is a danger that you can leave the GC in a state where its collection strategy has changed and is no longer optimal. You really do have to make sure that if you add <x> pressure, you later remove <x> pressure when the object is finalized. We like to keep the GC instance agnostic which is why we avoid tieing it to specific items.

As a note: FxCop will be a great help here, since we have rules in place to help ensure that if you AddPressure somewhere, that you also remove the pressure in the finalizer for the class.

As for HandleCollector: you're right, in that it is simply a helper class. It was something which we were using internally, and believe made sense to expose, since people were probably writing their own anyway.

I am sure we'll continue to expand on what's available in this area, and we're always interested to hear your ideas/suggestions for improvements. For example, I have taken note of the request to consider adding an 'AvailableForGC' method in a future release.
Monday, March 22, 2004 8:21 PM by Justin Rogers

# re: The new face of the GC in Whidbey... I'm not sure this is a pretty face...

If you might be able to comment on what the usage of AvailableForGC might be if there isn't any way to actually collect the object after making the examination? What can we do with this information if we do get it.

You also mention again, using the finalizer to make sure the memory gets removed. However, are we instead going to see the Dispose pattern being more important here? AKA, does it matter if the managed object is collected if the unmanaged memory has already been released. The only time the finalizer for a bitmap might be called is if the programmer is relaxed in his disposal of the resource. Now, in the Dispose pattern the finalizer does make sure to call the Dispose methods, so maybe that is what you guys are meaning.
Tuesday, March 23, 2004 4:26 AM by TrackBack

# Discussion on GC in Whidbey

Tuesday, March 23, 2004 4:58 AM by Iain

# re: The new face of the GC in Whidbey... I'm not sure this is a pretty face...

It occurs to me that sure, you could use this stuff to leak resources. However, the only real applicability is for stuff that wraps unmanaged resources - so utilising these could leak memory, but you will only have cause to use these if you already have the ability to leak memory.
Tuesday, March 23, 2004 9:30 AM by Doug McClean

# re: The new face of the GC in Whidbey... I'm not sure this is a pretty face...

To me, an AvailableForGC method doesn't make sense because it would be almost as expensive to implement as an actual garbage collection (e.g., you need to do the full marking pass of the garbage collector to figure out what the answer to this method is), so if you are going to see if something is AvailableForGC you might as well just do the GC and be done with it. Am I missing something?
Tuesday, March 23, 2004 9:22 PM by Justin Rogers

# re: The new face of the GC in Whidbey... I'm not sure this is a pretty face...

To Iain: Currently you can leak unmanaged resources, you are right. However, this leakage doesn't affect the GC at all, it has no impact.

Now, if you fail to call RemoveMemoryPressure, you are going to permanently (application lifetime I'm assuming) affect the GC and possibly cause more GCs than are necessary.

So rather than leak a single resource now, you are leaking a new pseudo resource. The pseudo resource is the additional memory pressure placed on the GC that is causing it to change it's heuristics and collect more often because it has been told some object consumes more memory than the GC can deduce.

Thinking really hard on this matter, I really think the memory pressure should be assigned an object instance, or at least have that option. If that object instance is ever collected, it is assumed that the memory pressure, if not already released by the object, gets released. I realize FXCop has rules for this type of thing, but for every developer using FXCop, there are 10 that don't.
Wednesday, November 17, 2004 7:18 AM by TrackBack

# GC on small managed resource holding large unmanaged resources..

GC on small managed resource holding large unmanaged resources..
Wednesday, May 23, 2007 9:51 PM by MaryJames

# re: The new face of the GC in Whidbey... I'm not sure this is a pretty face...

Hi  all

How I can change avatar in this forum?

Leave a Comment

(required) 
(required) 
(optional)
(required)