.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);
- }
- }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д