我最近采取了WCF Windows服务的所有权,使大量使用了下面的静态实用工具类的检索查找数据:这段代码为什么会造成内存泄漏?
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 MB的RAM。
在某些时候,一个团队成员认为需要通过创建一个由延迟加载的静态字段支持的静态属性来引入另一个级别的优化。无论如何,在几次调用服务之后,所述静态字段的存在会导致严重的内存泄漏(500MB +)。
当我删除静态字段和属性(客户端改为调用Utility.GetErrorData())时,内存消耗回到正常水平。
任何人都可以解释为什么这个静态字段的存在导致内存泄漏?如果这有所帮助,WCF服务将与InstanceContextMode.PerCall一起运行。
非常感谢。
你怎么知道这是造成内存泄漏?它是不是只是使用大量的内存,并保持它静止?什么是您的服务的实例?它是PerCall吗?辛格尔顿?会议? – 2011-06-04 18:52:40
它实际上是内存泄漏还是GC运行不够,或者认为它不需要释放内存。 – 2011-06-06 01:23:59
在DEBUG模式或RELEASE模式下运行?在RELEASE模式不会的情况下,DEBUG模式会泄漏。 – Felan 2011-06-08 20:26:34