我在.net 4.0控制檯應用程序中使用企業日誌記錄5.0。我注意到我的應用程序內存使用率非常高。我能確定,原因是由於以下電話:如何減少Enterprise Library 5.0記錄內存使用情況?
var logWriter = EnterpriseLibraryContainer.Current.GetInstance<LogWriter>();
一些剖析和手動測試用一個簡單的控制檯應用程序後,我能夠確定從45MB內存使用率下降至10MB時下列DLL從該執行文件夾中刪除:
- Microsoft.Practices.EnterpriseLibrary.Validation.dll
- Microsoft.Practices.EnterpriseLibrary.Data.dll
日誌初始化是我第一次調用企業庫API。我的控制檯應用程序不會調用Data.dll和Validation.dll。它們存在於我的執行文件夾中,因爲它們是其他類庫的參考和我們的部署設置。
我假設EnterpriseLibraryContainer.Current正在基於在執行文件夾中找到的內容進行初始化。我試圖創建我寫進程具有以下,但我得到了相同的結果:
var configSource = new FileConfigurationSource(configPath);
var logWriterFactory = new LogWriterFactory(configSource);
var logWriter = logWriterFactory.Create();
是否可以初始化一個寫進程,而不與驗證和數據增加了內存使用的DLL存在於執行文件夾?
更新: 因此,在entlib源內的一些調試。我相信以下是找到DLL並實例化Validation.dll和Data.dll,儘管在項目中根本沒有被引用。
從EntLib50Src \塊\ COMMON \ SRC \配置\ ContainerModel \ TypeLoadingLocator.cs
private IEnumerable<TypeRegistration> GetRegistrationsInternal(IConfigurationSource configurationSource,
Func<ITypeRegistrationsProvider, IConfigurationSource, IEnumerable<TypeRegistration>> registrationAccessor)
{
Type providerType = Type.GetType(Name);
if (providerType == null) return new TypeRegistration[0];
var provider = (ITypeRegistrationsProvider)Activator.CreateInstance(providerType);
return registrationAccessor(provider, configurationSource);
}
調用Type.GetType(名稱)看在執行程序集的位置,這似乎是它註冊entlib數據訪問的原因。
調試進一步我的原始應用程序,其中包含連接字符串與Oracle ODP.net供應商。 (我從一開始就沒有提到)
(我當前的應用程序執行不會調用或引用數據訪問,因爲應用程序使用對需要連接字符串的其他dll的動態調用來定義連接字符串。但對於我的測試我沒有調用任何這些調用)
由於找到了Microsoft.Practices.EnterpriseLibrary.Data.dll,因此EnterpriseLibrary繼續爲數據訪問類型默認註冊,並且我發現以下調用是造成巨大內存高峯的原因:
\ EntLib50Src \ Blocks \ Data \ Src \ Data \ Configuration \ DatabaseSyntheticConfigSettings.cs
private static DbProviderMapping GetDefaultMapping(string dbProviderName)
{
// try to short circuit by default name
if (DbProviderMapping.DefaultSqlProviderName.Equals(dbProviderName))
return defaultSqlMapping;
if (DbProviderMapping.DefaultOracleProviderName.Equals(dbProviderName))
return defaultOracleMapping;
// get the default based on type
var providerFactory = DbProviderFactories.GetFactory(dbProviderName);
if (SqlClientFactory.Instance == providerFactory)
return defaultSqlMapping;
if (OracleClientFactory.Instance == providerFactory)
return defaultOracleMapping;
return null;
}
的DbProviderFactories.GetFactory(dbProviderName)調用時dbProviderName = Oracle.DataAccess。Client.OracleClientFactory導致巨大的內存峯值。
所以看起來像是由於odp.net和其註冊DBFactories的事實導致的巨大內存高峯的原因。
看來我不能創建一個記錄器,而無需註冊執行裝配位置中的所有內容。理想情況下,除非明確告知,否則我不想註冊數據訪問。
也在這裏創建了一個討論: http://entlib.codeplex.com/discussions/287422 –