Memory Leak in Xmlserializer

Asked

Viewed 108 times

3

I have the code below. How the method is static and the XmlSerializer does not implement the Dispose, at each call of the method, the system stacks in memory or the GC (Garbage Collector) can clear this variable?

And in the case of classes that do not have Dispose, to destroy the variable I can do converter = null, or do I have to do something else? For in my understanding, null, only clears the value, but leaves the variable in the application pointer.

public static string ConverterObjetoEmTexto(object dados)
{
    var retorno = "";
    XmlSerializer converter = new XmlSerializer(dados.GetType());

    using (StringWriter textWriter = new StringWriter())
    {
        converter.Serialize(textWriter, dados);
        retorno = textWriter.ToString().Replace("encoding=\"utf-16\"", "encoding=\"utf-8\"");                           
        return retorno;
    }
}

2 answers

3


The XmlSerializer doesn’t need dispose() because it does not allocate resources. It only allocates memory, so when it terminates the execution of the method, the object will have no reference to it. It can be removed from memory at any time by GC.

This does not mean that it will occur on time, it may take time, but GC is smart enough to know the right time to remove from memory, will not cause you problems.

Local variables only exist during the execution of the method where they are contained. If your content does not escape from the method, the object pointed by the variable is orphaned and can be deleted at any time.

This differs from the StringWriter that has unmanaged resources allocated and needs to have a pattern to inform that it can be eliminated. That’s why you needed to use the using.

This code is correct and will not leak memory.

  • If by chance it happens that the Xmlserializer it inside a Try / catch, it would not generate memory leak?

  • No, you left the method, no matter how, the variable will be destroyed and the object will be orphaned and can be collected at any time. The variable is in the stack (in this case). The object is in the heap. http://answall.com/q/3797/101

2

There are basically 2 rules where the implementation of Idisposable is required:

  1. The object maintains unmanaged resources;
  2. The object maintains managed resources that implement Idisposable;

Xmlserializer does not fall under any of these rules.

Idisposable is usually implemented in conjunction with ~finalizer() so that if Ispose() is not called, this will be done when the object is destroyed.

https://msdn.microsoft.com/pt-br/library/ms244737.aspx

PS: A more efficient implementation of your Converterobjetoemtext follows below:

    public static string ConverterObjetoEmTexto(object dados)
    {
        var sb = new StringBuilder();
        using (var textWriter = new EncodedStringWriter(sb, Encoding.UTF8))
        {
            new XmlSerializer(dados.GetType()).Serialize(textWriter, dados);
            return sb.ToString();
        }
    }

You’ll need this class:

    public class EncodedStringWriter : StringWriter
    {
        private readonly Encoding encoding;

        public EncodedStringWriter(StringBuilder stringBuilder, Encoding encoding) : base(stringBuilder)
        {
            this.encoding = encoding;
        }

        public override Encoding Encoding
        {
            get
            {
                return encoding;
            }
        }
    }

Browser other questions tagged

You are not signed in. Login or sign up in order to post.