Possible memory leak in DelegatingHandler?

Topics: Web Api
Oct 19, 2011 at 7:16 AM

Hi,

I and my colleague have discovered a potential memory leak in the DelegatingHandler. During the performance testing of the services we are developing we found out that the memory consumption of the W3WP.exe-process hosting our services was constantly increasing for every request. After investigating this for a while we found out that the problem was related to our custom DelegatingHandler, since the memory consumption was stable after we removed our DelegatingHandler. We decided to take a memory dump and found out that the top 5 types in the heap were the following:

System.Threading.CancellationTokenRegistration[]
System.Object[]
System.Threading.CancellationTokenSource
System.Threading.CancellationCallbackInfo
System.Threading.SparselyPopulatedArrayFragment`1[[System.Threading.CancellationCallbackInfo, mscorlib]]

The DelegatingHandler method SendAsync takes a CancellationToken, and without digging deeper in the Web Api framework we can see a link between the CancellationToken and the findings in the heap.

In order to eliminate the possibility that our own code was causing any problem we made a simple application with just one simple resource that has a GET operation. We also created a custom ServiceHostFactory and a custom DelegatingHandler:

public class HostFactory : ServiceHostFactory
{
	protected override System.ServiceModel.ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
	{
		var config = new HttpConfiguration
			{
				MessageHandlerFactory = () => new[] { new CustomDelegatingHandler() }
			};
		return new HttpServiceHost(serviceType, config, baseAddresses);
	}
}

public class CustomDelegatingHandler : DelegatingHandler
{
	protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
	{
		return base.SendAsync(request, cancellationToken);
	}
}

 

The routing setup is as follows:

var hostFactory = new HostFactory();
RouteTable.Routes.Add(new ServiceRoute("MyResource", hostFactory, typeof (MyResource)));

 

Can someone please explain to me if we are using the DelegatingHandler totally wrong or if this is a normal behavior? Have anyone else been facing the same problem?

 

Best regards,
Martin Thern
tretton37.com 

Oct 19, 2011 at 2:41 PM

Martin,

Thanks for the thorough investigation – we will have a look how to fix this.

Henrik

From: Thern [email removed]
Sent: Wednesday, October 19, 2011 00:17
To: Henrik Frystyk Nielsen
Subject: Possible memory leak in DelegatingHandler? [wcf:276398]

From: Thern

Hi,

I and my colleague have discovered a potential memory leak in the DelegatingHandler. During the performance testing of the services we are developing we found out that the memory consumption of the W3WP.exe-process hosting our services was constantly increasing for every request. After investigating this for a while we found out that the problem was related to our custom DelegatingHandler, since the memory consumption was stable after we removed our DelegatingHandler. We decided to take a memory dump and found out that the top 5 types in the heap were the following:

System.Threading.CancellationTokenRegistration[]
System.Object[]
System.Threading.CancellationTokenSource
System.Threading.CancellationCallbackInfo
System.Threading.SparselyPopulatedArrayFragment`1[[System.Threading.CancellationCallbackInfo, mscorlib]]

The DelegatingHandler method SendAsync takes a CancellationToken, and without digging deeper in the Web Api framework we can see a link between the CancellationToken and the findings in the heap.

In order to eliminate the possibility that our own code was causing any problem we made a simple application with just one simple resource that has a GET operation. We also created a custom ServiceHostFactory and a custom DelegatingHandler:

public class HostFactory : ServiceHostFactory
{
        protected override System.ServiceModel.ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
        {
               var config = new HttpConfiguration
                       {
                               MessageHandlerFactory = () => new[] { new CustomDelegatingHandler() }
                       };
               return new HttpServiceHost(serviceType, config, baseAddresses);
        }
}
 
public class CustomDelegatingHandler : DelegatingHandler
{
        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
               return base.SendAsync(request, cancellationToken);
        }
}

The routing setup is as follows:

var hostFactory = new HostFactory();
RouteTable.Routes.Add(new ServiceRoute("MyResource", hostFactory, typeof (MyResource)));

Can someone please explain to me if we are using the DelegatingHandler totally wrong or if this is a normal behavior? Have anyone else been facing the same problem?

Best regards,
Martin Thern
tretton37.com

Coordinator
Oct 19, 2011 at 4:28 PM

Martin, could you please open an issue in the Issue Tracker for this with as much information as you have for reproducing the issue?

Thanks.

Daniel Roth

Oct 21, 2011 at 7:35 AM

I have created an issue. Just tell me if you need any more information.

 

Best regards,
Martin Thern