내 WCF REST 서비스 내에서 사용되는 AutoMapper 및 StructureMap 사용 내에서 메모리 누수가있는 것 같습니다.구조지도 automapper 메모리 누출?
언로드 테스트에서 메모리 사용량이 지속적으로 증가하는 것을 볼 수 있었고 메모리 프로파일 러를 사용하여 메모리 프로파일을보다 자세히 조사했을 때 MappingEngine 구축에 사용 된 많은 인스턴스가 있음을 알 수 있습니다 (약 9x 다른 예) 여기
Class Name=Live Instances
Object=498,847
Int32[]=69,373
Object[]=68,116
ConcurrentDictionary<TKey, TValue>+Node<TypePair, IObjectMapper>=37,624
string=35,240
IObjectMapper[]=30,782
EventHandler<TypeMapCreatedEventArgs>=30,782
MappingEngine=30,781
ConcurrentDictionary<TypePair, IObjectMapper>=30,781
ConcurrentDictionary<TKey, TValue>+Node<TypePair, LambdaExpression>[]=30,781
ConcurrentDictionary<TKey, TValue>+Node<TypePair, IObjectMapper>[]=30,781
ConcurrentDictionary<TypePair, LambdaExpression>=30,781
및 쓰레기 형식의 전형적인 예를 보유 그래프 ...
bootstrapper._configuration
-> AutoMapper.ConfigurationStore (TypeMapCreated)
-> System.EventHandler<TypeMapCreatedEventArgs> (multicast delegate)
-> System.Object[]
-> System.EventHandler<TypeMapCreatedEventArgs>
-> AutoMapper.MappingEngine (_objectMapperCache)
-> System.Collections.Concurrent.ConcurrentDictionary<Internal.typePair, IObjectMapper> (m_locks)
-> System.Object[]
-> System.Object
(죄송하지만 SO 나
) 이미지를 게시하지 것이다
문제는 코드, StructureMap 또는 AutoMapper에 문제가 있는지 잘 모르겠습니다.
가스트 래퍼에 대한 오토 (Global.asax에 위해 Application_Start에서 호출)
코드 샘플 ...
private void AutoMapperRegistration()
{
For<ConfigurationStore>().Singleton().Use<ConfigurationStore>().Ctor<IEnumerable<IObjectMapper>>().Is(AutoMapper.Mappers.MapperRegistry.AllMappers());
For<IConfigurationProvider>().Use(ctx => ctx.GetInstance<ConfigurationStore>());
For<IConfiguration>().Use(ctx => ctx.GetInstance<ConfigurationStore>());
For<ITypeMapFactory>().Use<TypeMapFactory>();
For<IMappingEngine>().Use<MappingEngine>();
Scan(scan =>
{
scan.AssemblyContainingType<AppRegistry>();
scan.AddAllTypesOf<Profile>();
});
}
...와 StructureMap 내에 구성된
public class BootStrapper
{
private static readonly IConfiguration _configuration = ObjectFactory.GetInstance<IConfiguration>();
public static void Initialize()
{
_configuration.AddProfile<AutoMapperProfile>();
}
public class AutoMapperProfile : Profile
{
protected override void Configure()
{
BootstrapAutoMapper();
}
}
public static void BootstrapAutoMapper()
{
_configuration.CreateMap<In.Account, Out.Accounts.Account>()
.ForMember(m => m.AccountNumber, o => o.MapFrom(s => s.AcctId))
.ForMember(m => m.Balances, o => o.Ignore())
.ForMember(m => m.AccountTypeDescription, o => o.MapFrom(s => s.TypeName))
.ForMember(m => m.AccountType, o => o.MapFrom(s => s.Type))
.ForMember(m => m.IsNoticeAccount, o => o.ResolveUsing(s => IsNoticeAccountMapper.Map(s.Type, ObjectFactory.GetInstance<IAccountTypeHelper>())));
// many other mappings excluded for brevity
}
}
일반적인 WCF 휴식 서비스 사용 ...
public class AccountService : IAccountService
{
private readonly IMappingEngine _mappingEngine;
private readonly IAccountFacade _accountFacade;
public AccountService(IMappingEngine mappingEngine, IAccountFacade accountFacade)
{
_mappingEngine = mappingEngine;
_accountFacade = accountFacade;
}
public IEnumerable<Account> GetAccounts()
{
var ret = new List<Account>();
var entities = _accountFacade.GetAccounts().ToList();
foreach (var account in entities.Select(entity => _mappingEngine.Map<In.Account, Out.Account>(entity)))
{
ret.Add(account);
}
return ret;
}
}