WmiChannels memory leak

Posted on November 18, 2010 by

0


The following bug happens in a very specific scenario in which one element is both the server side for one WCF operation, and the client side for another  WCF operation, and all services work in a singleton mode (the InstanceContextMode is single). Since we encounter this scenario, and spent hours trying to analyze it, we thought we might not be the only ones, and this post can be useful for others …

Symptom

This bug happens only in .Net 3.5 when there is a load from the following scenario:

  1. “A” starts a WCF operation very often
  2. “B” is also the server side for the operation that started from “A” and also the client side for the operation to “C”.
  3. The channel from “B” to “C” often get faulted (for example “C” is sometimes down), and “B” calls Abort() on the channel, and creates in this case a new one.

FLOW

After a while, you will noticea huge memory  consumption of WmiChannels (System.ServiceModel.Channels.IChannel) from the InstanceContext object.

0:023>  !dumpheap -mt 000006427890a110

…
000000015cd256d8 000006427890a110       48     
000000015cd25b50 000006427890a110       48     
000000015cd28030 000006427890a110       56     
000000015e258dd8 000006427890a110       40     
00000001afff0080 000006427890a110  1048608     
00000001b00f00a0 000006427890a110   262176     
00000001b01300d8 000006427890a110   262176     
00000001b0170110 000006427890a110   262176     
00000001b01b0148 000006427890a110   262176     
00000001b01f0180 000006427890a110   262176     
00000001b02501e8 000006427890a110   262176     
00000001b02f0280 000006427890a110   262176     
00000001b03302b8 000006427890a110   262176     
00000001b03702f0 000006427890a110   262176     
total 458184 objects
------------------------------
total 1735626 objects
Statistics:
              MT    Count    TotalSize Class Name
000006427890a110  1735626    110872808 System.Object[]
Total 1735626 objects

0:023> !dumpobj 00000001afff0080 
Name: System.Object[]
MethodTable: 000006427890a110
EEClass: 000006427890ab08
Size: 1048608(0x100020) bytes
Array: Rank 1, Number of elements 131072, Type CLASS
Element Type: System.ServiceModel.Channels.IChannel
Fields:
None

The reason this memory leak happens is that when calling CreateChannel(Type, EndpointAddress, Uri ), the following lines are executed:

 if ((current != null) && (current.InstanceContext != null))
 {
     current.InstanceContext.WmiChannels.Add((IChannel)serviceChannel.Proxy);
     serviceChannel.WmiInstanceContext = current.InstanceContext;
 }

WmiChannel is created, and added on the InstanceContext object. The problem is that Remove from WmiChannels collection (WmiChannels.Remove((IChannel)) is called only in “OnClose()” and not in “onAbort()”.

Since this is a singleton mode, and it’s the same InstanceContext object for all requests,

the list of wmichannels is getting larger all the time, and its never cleaned.

Solution

This problem is solved in .Net 4.0.

There are several workarounds for the problem in .Net 3.5:

One solution is to change the InstanceMode of the services from singleton to PerCall. If this is not possible, the call from “B” to “C” will have to be executed on a different thread.

Advertisements
Posted in: Pitfalls