OP answer - Я нашел какой-то оскорбительный код (и нет, для такого веб-сервиса, как этот, ненормально использовать больше 5 ГБ памяти). Некоторое время назад, пытаясь создать свои собственные пространства имен в xml, возвращенном веб-службой, я добавил класс CustomNamespaceXmlFormatter, указанный в этом посте, в ответе @Konamiman: Удалить пространство имен в xml Комментарий ниже это упоминает проблему утечки памяти. Хотя ANTS Memory Profiler никогда не показывал, что мой веб-сервис генерирует несколько динамических сборок, я, тем не менее, обновил код, чтобы использовать нечто похожее на одноэлементный шаблон для создания экземпляров XmlSerializer, как показано ниже, и теперь мое использование памяти находится под контролем (и фактически снижается). когда закончится обработка запросов!).
public class CustomNamespaceXmlFormatter : XmlMediaTypeFormatter
{
private readonly string defaultRootNamespace;
public CustomNamespaceXmlFormatter() : this(string.Empty)
{
}
public CustomNamespaceXmlFormatter(string defaultRootNamespace)
{
this.defaultRootNamespace = defaultRootNamespace;
}
public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
{
if (type == typeof(String))
{
//If all we want to do is return a string, just send to output as <string>value</string>
return base.WriteToStreamAsync(type, value, writeStream, content, transportContext);
}
else
{
XmlRootAttribute xmlRootAttribute = (XmlRootAttribute)type.GetCustomAttributes(typeof(XmlRootAttribute), true)[0];
if (xmlRootAttribute == null)
xmlRootAttribute = new XmlRootAttribute(type.Name)
{
Namespace = defaultRootNamespace
};
else if (xmlRootAttribute.Namespace == null)
xmlRootAttribute = new XmlRootAttribute(xmlRootAttribute.ElementName)
{
Namespace = defaultRootNamespace
};
var xns = new XmlSerializerNamespaces();
xns.Add(string.Empty, xmlRootAttribute.Namespace);
return Task.Factory.StartNew(() =>
{
//var serializer = new XmlSerializer(type, xmlRootAttribute); **OLD CODE**
var serializer = XmlSerializerInstance.GetSerializer(type, xmlRootAttribute);
serializer.Serialize(writeStream, value, xns);
});
}
}
}
public static class XmlSerializerInstance
{
public static object _lock = new object();
public static Dictionary<string, XmlSerializer> _serializers = new Dictionary<string, XmlSerializer>();
public static XmlSerializer GetSerializer(Type type, XmlRootAttribute xra)
{
lock (_lock)
{
var key = $"{type}|{xra}";
if (!_serializers.TryGetValue(key, out XmlSerializer serializer))
{
if (type != null && xra != null)
{
serializer = new XmlSerializer(type, xra);
}
_serializers.Add(key, serializer);
}
return serializer;
}
}
}