Castle windsor代理生成内存泄漏

时间:2017-02-16 11:03:20

标签: c# asp.net-mvc memory-leaks castle-windsor dynamic-proxy

Castle windsor用于MVC应用程序,如下所述: Plugging Windsor in MVC

在我的应用程序中有一个区别,那就是方法AddControllerLoggingFunctionality:

var controller = ((IController)container.Kernel.Resolve(controllerType)).AddControllerLoggingFunctionality();

此方法位于logger类中:

[DebuggerStepThrough]
public static class Logger
{
    private static readonly Castle.DynamicProxy.ProxyGenerator proxyGenerator;
    static Logger()
    {
        proxyGenerator = new Castle.DynamicProxy.ProxyGenerator();
        Castle.DynamicProxy.Generators.AttributesToAvoidReplicating.Add(
            typeof(ServiceContractAttribute));
    }

    public static TInterface AddControllerLoggingFunctionality<TInterface>(this TInterface implementation)
        where TInterface : class
    {
        if (implementation == null)
        {
            throw new ArgumentNullException("implementation");
        }

        if (!typeof(TInterface).IsInterface)
        {
            throw new Exception("Type of 'TInterface' must be interface.");
        }

        Castle.DynamicProxy.ProxyGenerationOptions options =
            new Castle.DynamicProxy.ProxyGenerationOptions();

        var origAttribs = implementation.GetType().GetCustomAttributesData();
        if (origAttribs != null)
        {
            foreach (var origAttrib in origAttribs)
            {
                options.AdditionalAttributes.Add(
                    AttributeUtil.CreateBuilder(origAttrib));
            }
        }

        return (TInterface)proxyGenerator.CreateInterfaceProxyWithTarget<TInterface>(
            implementation,
            options,
            new ControllerLoggingInterceptor(implementation.GetType()));
    }
}

和 有人可以解释一下吗?为什么IController可以调用AddControllerLoggingFunctionality以及它是什么?

由于此更改,此控制器永远不会从内存中释放(何时 container.Kernel.ReleaseComponent(控制器);被称为)我得到内存泄漏。 &#34;对象由发布政策跟踪&#34;计数器一直在增加。 如果我删除AddControllerLoggingFunctionality,那么&#34;对象由发布策略跟踪#34;每当我调用ReleaseComponent并且内存泄漏没有发生时,计数器减少。

1 个答案:

答案 0 :(得分:2)

你不能在控制器上调用Release(),而是在你手动创建的代理上调用它,因此Release()只是对温莎的无操作,因为它不知道关于该对象,因此继续跟踪控制器组件。

如果你使用Windsor的built-in interception support,你不必担心这个问题,因为Windsor在通过自己的内部托管代理时会知道如何处理该组件。

如果您想在更改为Windsor的内置支持之前对其进行测试,请将代理转换为Castle.DynamicProxy.IProxyTargetAccessor并致电DynProxyGetTarget()以获取您需要的控制器实例传递给Release()

(此答案是从Castle Users邮件列表中的discussion复制而来的)