.NET 4.x утечка памяти - C#

Узнай цену своей работы

Формулировка задачи:

есть код
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;
        }
Но при большом количестве объектов которые надо десериализовать (около 3000) Он выжирает 1,5 гига приватной и после окончания работы не отдаёт. В итоге прога после пары запусков процесса падает с outofmemoryexception. Что не так? Сам косяка не вижу. PS: Метод статический и находится в статическом классе.

Решение задачи: «.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);
            }
        }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

5   голосов , оценка 4.6 из 5