2012-12-07 7 views
0

내 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;  
     } 
} 

답변

1

MappingEngine 구성으로 인해 문제가 발생한 것으로 보입니다. 싱글 톤으로 설정해야 할 필요가있었습니다. 그렇지 않으면 IDisposable이므로 인스턴스가 지워지지 않았습니다.

그래서 설정을 변경 ..

For<IMappingEngine>().Singleton().Use<MappingEngine>();