我正在努力了解我的内存泄漏来自哪里。我有一个我在研究时遇到的帖子的修改版本。我们使用 StructureMap,我们想为 MiniProfiler 使用 AOP,所以这似乎是一个完美的尝试,但是当我实现它时,我开始出现大量内存泄漏。我将泄漏追踪到创建代理的位置。如果我让所有其他代码保持不变并删除.EnrichWith(...)
调用,内存泄漏就会消失。我在 Bootstrapper 类中创建代理类,如下所示:
x.For<IServiceInterface>()
.Use<ServiceClass>()
.EnrichWith(ex => DynamicProxyHelper.
CreateInterfaceProxyWithTargetInterface(typeof(IServiceInterface), ex));
动态代理助手类:
public class DynamicProxyHelper
{
public static IEnumerable<Type> GetScannableTypes()
{
var types = Assembly.GetExecutingAssembly().GetTypes();
var scannableTypes = new List<Type>();
foreach (var type in types)
{
// http://www.hanselman.com/blog/DoesATypeImplementAnInterface.aspx
if (typeof (IAttributeScanTask).IsAssignableFrom(type)
&& type.FullName != typeof (IAttributeScanTask).FullName)
{
scannableTypes.Add(type);
}
}
return scannableTypes;
}
public static object CreateInterfaceProxyWithTargetInterface<T>(Type interfaceType, T obj)
{
if (!interfaceType.IsInstanceOfType(obj))
{
throw new ArgumentException(
"DynamicProxyHelper: Object passed to the proxy must inherit from the interface type passed to the proxy.");
}
// Create the proxy and return the result
var dynamicProxy = new ProxyGenerator();
var scannableTypes = GetScannableTypes();
var result = dynamicProxy.CreateInterfaceProxyWithTargetInterface(
interfaceType,
obj,
new IInterceptor[] { new MyInterceptor(obj.GetType(), new AttributeScanEngine(), scannableTypes)} );
return result;
}
}
和 MyInterceptor 类:
public interface IMyInterceptor : IInterceptor {}
public class MyInterceptor : IMyInterceptor
{
private readonly Type _concreteType;
private readonly IAttributeScanEngine _scanEngine;
private readonly IEnumerable<Type> _scannableTypes;
private const string AttributeNameSpace = "MyAttributes";
public MyInterceptor() : this(typeof(object), new AttributeScanEngine(), new List<Type>()){}
public MyInterceptor(Type concreteType, IAttributeScanEngine scanEngine, IEnumerable<Type> scannableTypes)
{
_concreteType = concreteType;
_scanEngine = scanEngine;
_scannableTypes = scannableTypes;
}
public void Intercept(IInvocation invocation)
{
var scanType = ResolveScanType(invocation);
// We found a matching attribute that can be applied
if (scanType != null)
{
// execute the custom task we need to run
_scanEngine.Run(invocation, scanType, _concreteType);
}
else
{
// no scanned types could be found so execute the method as is
invocation.Proceed();
}
}
protected internal virtual Type ResolveScanType(IInvocation invocation)
{
foreach (var type in _scannableTypes)
{
var attributeName = GetAttributeName(type.Name);
var attributeType = Type.GetType(attributeName);
if (attributeType != null)
{
var attributeDecoration = Attribute.GetCustomAttribute(invocation.GetConcreteMethodInvocationTarget(), attributeType, true);
// We found an attribute for this scan type
if (attributeDecoration != null)
{
return type;
}
}
}
return null;
}
protected internal virtual string GetAttributeName(string typeName)
{
var aspectName = typeName.Substring(0, typeName.IndexOf("ScanTask"));
return AttributeNameSpace + "." + aspectName + "Attribute";
}
}
我相信这与通过调用创建代理有关,EnrichWith
因为如果我将代码的所有其他部分保持不变并简单地删除该调用,内存泄漏就会消失。我在这里做错了什么基本的事情吗?