.NET 4.x утечка памяти - C#
Формулировка задачи:
есть код
Но при большом количестве объектов которые надо десериализовать (около 3000)
Он выжирает 1,5 гига приватной и после окончания работы не отдаёт. В итоге прога после пары запусков процесса падает с outofmemoryexception.
Что не так? Сам косяка не вижу.
PS: Метод статический и находится в статическом классе.
private static Object XmlDeserialize(Type t, String xmlDoc, String xmlRoot)
{
if (String.IsNullOrEmpty(xmlDoc))
{
return t.GetConstructors().FirstOrDefault(x => x.GetParameters().Length == 0)?.Invoke(null);
}
/// В коде ниже утечка
var serializer = String.IsNullOrEmpty(xmlRoot) ? new XmlSerializer(t) : new XmlSerializer(t, new XmlRootAttribute(xmlRoot));
using (var memoryStream = new MemoryStream(StringToUtf8ByteArray(xmlDoc)))
{
return serializer.Deserialize(memoryStream);
}
}
// Метод конвертирует строку в UTF8 Byte массив
private static Byte[] StringToUtf8ByteArray(string xmlString)
{
UTF8Encoding encoding = new UTF8Encoding();
var byteArray = encoding.GetBytes(xmlString);
return byteArray;
}Решение задачи: «.NET 4.x утечка памяти»
textual
Листинг программы
private static readonly Hashtable Serializers = new Hashtable();
private static Object XmlDeserialize(Type t, String xmlDoc, String xmlRoot)
{
if (String.IsNullOrEmpty(xmlDoc))
{
return t.GetConstructors().FirstOrDefault(x => x.GetParameters().Length == 0)?.Invoke(null);
}
//https://msdn.microsoft.com/ru-ru/library/system.xml.serialization.xmlserializer(v=vs.110).aspx
//If you use any of the other constructors, multiple versions of the same assembly are generated and never unloaded, which results in a memory leak and poor performance.
//The easiest solution is to use one of the previously mentioned two constructors. Otherwise, you must cache the assemblies in a Hashtable, as shown in the following example.
var key = new { t.FullName, xmlRoot };
XmlSerializer serializer;
if (Serializers.Contains(key))
{
serializer = (XmlSerializer)Serializers[key];
}
else
{
serializer = String.IsNullOrEmpty(xmlRoot) ? new XmlSerializer(t) : new XmlSerializer(t, new XmlRootAttribute(xmlRoot));
Serializers.Add(key, serializer);
}
using (var memoryStream = new MemoryStream(StringToUtf8ByteArray(xmlDoc)))
{
return serializer.Deserialize(memoryStream);
}
}