1 year ago

#287303

test-img

ZeniFlow

Castle Windsor resolving more dependencies than it releases with SignalR Activator

I don't know if my analyse is correct or not. But i'm facing some memory leak with castle and SignalR. It's a well known "issue" for Transient registered components see for example (SignalR server memory consumption (Windsor IHubActivator to blame?) / https://github.com/SignalR/SignalR/issues/3208 and a lot of others).

I'm using this SignalR activator :


public class SignalRHubActivator : IHubActivator
    {
        private readonly IWindsorContainer _container;

        public SignalRHubActivator(IWindsorContainer container)
        {
            _container = container ?? throw new ArgumentNullException("container");
        }

        private int GetTrackedComponentsCount()
        {
            var host = (IDiagnosticsHost)ContainerManager.Container.Kernel.GetSubSystem(SubSystemConstants.DiagnosticsKey);
            var diagnostics = host.GetDiagnostic<ITrackedComponentsDiagnostic>();
            var inspect = diagnostics.Inspect();
            var all = inspect
                .Select(x => new { Name = x.Key.ComponentModel.ToString(), Count = x.Count() }).ToList();
            return all.Sum(x => x.Count);
        }
        public IHub Create(HubDescriptor descriptor)
        {
            var logger = _container.Resolve<ILogger>();

            var beforeResolvingCount = GetTrackedComponentsCount();
            logger.Info($"BEFORE Resolving - In SignalR Activator. Components waiting to release : {beforeResolvingCount}");
            
            var instance = _container.Resolve(descriptor.HubType) as IHub;
            var beforeReleasingCount = GetTrackedComponentsCount();
            logger.Info($"Before Releasing  - In SignalR Activator. Components waiting to release : {beforeReleasingCount} |  Difference {beforeResolvingCount - beforeReleasingCount}");

            _container.Release(instance);

            var afterReleasingCount = GetTrackedComponentsCount();
            logger.Info($"After Releasing  - In SignalR Activator. Components waiting to release : {afterReleasingCount} | Difference {beforeReleasingCount - afterReleasingCount}");
            return instance;
        }
    }

You can see that I have added some logs to see the number of tracked components to be released. AS you may know castle with its default Release Policy keep tracks of Transient components that needs to be released (for some reason). And it prevents them to be collected by the Garbage collector. My hubs are registered to be Transient, so Castle container should keep track them when I resolve a Hub. And that's what happen, you can see that i add 3 logs. Each time i log the number of Castle Windsor Tracked Components.

  • For the first time it logs me 0 because nothing has been resolve at that time.
  • For the second log, we can see that that number changes, in my case 456 (that's a lot I know)
  • For the third time, it should be 0 because, i released the hub... But for some reason that i don't know it's printed 436... So only 20 components are removed from tracked components... Even i release the entry object ...

Does anyone have any idea why i have this strange behaviour ? Why Castle Windsor still keep track of the dependencies of my Hub?

I checked in the Castle Windsor code and we can see that when an component is released, the dependencies of that component are also released :

https://github.com/castleproject/Windsor/blob/master/src/Castle.Windsor/MicroKernel/Burden.cs#L132

And of course we can see in the logs that it releases more than one component... So it actually releasing some dependencies but not all. Why ?

Thank you for reading me ! I hope i can have more info about the issue or the misunderstanding.

Edit : The problem wasn't Castle Windsor releasing feature. The problem was that i was registering the dependencies of my Hub using HybridPerWebRequestTransient() method from a old package. Which is not totally the same as registering them as Transient.

c#

signalr

castle-windsor

0 Answers

Your Answer

Accepted video resources