Trond-Eirik is rambling on about stuff

General stuff about system architecture and development

Friday, June 01, 2007

.Net 3.0 is doing more for leaky .Net applications

After a bumpy start with .Net 1.1 (1.0 does not count) where several issues regarding memory consumption and especially releasing memory .Net seems to be going in the right direction.

.Net has always been memory "hungry". The ide seems to be based on "unused memory is doing no good to anyone".
So, problably based one something like that, MS seems to have decided that any .Net application should grap a really good chunk of memory if available.

And that idea is resonable enough, in some closed single user fantasy world!

It soon became clear that altough .Net 1.1 applications was great at hugging memory, they were not so great at freeing it. Basically, whatever memory a .Net 1.1 application had got it's gready fingers on, was lost forever (or at least until the app closed down). In a multi user envirment with a lot of users running their applications over a long time this behaviour would very fast lead to out-of-memory exceptions as the first 20 instances of the application has already used all available memory.

In .Net 2.0 this seems to have improved a great deal, and from what I can see the behaviour and freeing of memory is mutch better. Now an application actually seems to be able to release back some memory without shutting it down first.

Now, in .Net 3.0 it finally seems as MS have understood that it is not enought to say: "Hey, we have a managed language and a garbage collector"

You will still have memory issue if you do the wrong stuff. One of the sources for doing the wrong stuff is event handlers.

Whenever you start listening to event from a event source using += you are actually creating a reference to that object. If you do not remove that reference, the event subscriber will be kept in memory as long as the event source is alive.
If you for example hooks up to the Application.Idle event in a form, that form will not be available for the GC as long as the application is executing.

On of these issues that is really important to consider is notification enabled collections. For example collections that implements IBindingList or just implements change events.
Say that you have one such collection with 1000 items within. Then you create a reference to one of those 1000 items.

For a "normal" collection, the collection has a reference to all items within the collection, the items in the collection has no reference to the collection. As soon as you no longer holds on to the collection itself, the collection and the 999 items that you are not refering to becomes available for the GC.

If you have an event enabled list, the list must to be able to notify any listeners of changes in any object within the list. To do this the list has to subscribe to events from all the entities contained within the list.
Using regular events this will create a reference from the objects within the collection to the collection itself.

So, that single object in the list that you made a reference to will now also causes the list itself, and therby all the 999 other objects to be unavailable for the GC.
This is of course not very nice when it comes to memory consumption.

I soon discovered this when working with the business layer of ByggOffice. To handle and avoid this situation I made a couple of specialized interfaces and a managment class that used the WeakReference object to support multicast events. The weak references made it possible to dispatch the events and at the same time make ureferenced entities available for the GC.
This solution worked out very well.

Now, in .Net 3.0 MS has finally started to take this issue serious and have introduced stuff as the WeakEventManager class and IWeakEventListner interface.
They are also doing a lot of referals towords the "weak event pattern":

"In typical applications, it is possible that handlers that are attached to event sources will not be destroyed in coordination with the listener object that attached the handler to the source. This situation can lead to memory leaks. Windows Presentation Foundation (WPF) introduces a particular design pattern that can be used to address this issue, by providing a dedicated manager class for particular events and implementing an interface on listeners for that event. This design pattern is known as the WeakEvent pattern."

You can read more about the "WeakEvent pattern" here: http://msdn2.microsoft.com/en-us/library/aa970850.aspx

Labels:

1 Comments:

At 11:36 PM, Blogger Unknown said...

data filtering it offers custom error information to which controls can bind. During data binding, this allows controls to retrieve specific error information from the data source itself

 

Post a Comment

<< Home