Я недавно стал владельцем службы Windows WCF, которая интенсивно использует следующий статический класс Utility для извлечения данных поиска:
public static class Utility
{
//begin code that causes increased memory consumption
private static Dictionary<string, ErrorData> _errorData;
internal static Dictionary<string, ErrorData> ErrorData
{
get
{
if (_errorData == null)
{
_errorData = GetErrorData();
}
return _errorData;
}
}
//end code that causes increased memory consumption
/// GetErrorData method to get error messages from error xml
/// </summary>
/// <returns>Dictionary of Error messages value for different fields.</returns>
internal static Dictionary<string, ErrorData> GetErrorData()
{
Dictionary<string, ErrorData> data = null;
XmlDocument doc = LoadXmlDocument(Constants.ErrorMessagesFileName);
XmlNodeList errorNode = doc.SelectNodes("/ErrorMessages/Error");
data = new Dictionary<string, ErrorData>();
foreach (XmlNode node in errorNode)
{
ErrorData errorValues = new ErrorData();
errorValues.FieldName = node.Attributes["FieldName"].Value;
errorValues.ErrorMessage = node.Attributes["ErrorMessage"].Value;
data.Add(node.Attributes["code"].Value, errorValues);
}
return data;
}
internal static XmlDocument LoadXmlDocument(string xmlFileName)
{
XmlDocument doc = null;
try
{
if (HttpRuntime.Cache[xmlFileName] == null)
{
doc = new XmlDocument();
doc.Load(Constants.Folderpath + "\\" + xmlFileName);
HttpRuntime.Cache.Insert(xmlFileName, doc);
}
else
{
doc = (XmlDocument)HttpRuntime.Cache[xmlFileName];
}
}
catch (Exception ex)
{
//log
}
return doc;
}
}
Как видите, статическое свойство ErrorData используетчастное поле поддержки.ErrorData - это словарь, который создается с использованием ресурса XML в файловой системе, поэтому содержимое файла сохраняется в HttpRuntime.Cache при первоначальном извлечении.
При нормальной нагрузке служба потребляет около 120 МБ ОЗУ.
В какой-то момент член команды почувствовал необходимость ввести другой уровень оптимизации, создав статическое свойство, поддерживаемое ленивозагружено статическое поле.В любом случае, наличие указанного статического поля вызывает довольно серьезную утечку памяти (500 МБ +) после нескольких обращений в службу.
Когда я удаляю статическое поле и свойство (клиенты вместо этого вызывают Utility.GetErrorData ()), потребление памяти возвращается к нормальному уровню.
Может кто-нибудь объяснить, почему наличие этого статического полявызывает утечку памяти?Служба WCF работает с InstanceContextMode.PerCall, если это имеет значение.
Большое спасибо.