1

Finally solution for everything described below is to install DotNet v4.5 on computers where my application is running, even though my application was developed and designed for DotNet v4.0

I am facing memory leak when COM to USB converter unplugged from computer. Memory dump shows me that I have hundreds of new System.Threading.OverlappedData object.

Type        System.Threading.OverlappedData
New objects   246368
New bytes    16753024
Dead bytes      0
Bytes delta 16753024

Type System.IO.Ports.SerialStream+SerialStreamAsyncResult
New objects  246353
New bytes   9854120
Dead bytes  0
Bytes delta 9854120

Type    System.Threading._IOCompletionCallback
New objects  246352
New bytes   6897856
Dead bytes  0
Bytes delta 6897856

My test application just opens port and has no event listeners. using System;

using System.IO.Ports;
using System.Text;

namespace OpenSerialPortApp
{
    class Program
    {
        static void Main(string[] args)
        {
            var Sp = new SerialPort
            {
                StopBits = StopBits.One,
                BaudRate = 9600,
                DataBits = 8,
                Parity = Parity.None,
                Encoding = Encoding.UTF8,
                PortName = "COM5"
            };

            Console.WriteLine("Port Created");

            Sp.Open();

            Console.WriteLine("Port started");

            //No I just unplug my COM to USB converter. 

            Console.ReadKey();
        }
    }
}

I tried to Close and Dispose serial port when it becomes unplugged. but it makes no big difference. It decreases amount of memory leak but does not fix my problem.

private void CloseAndDisposeSerialPort()
{
    var localRefToPort = DeviceSerialPort;
    DeviceSerialPort = null;
    try
    {
        if (localRefToPort == null) return;
        try
        {

            localRefToPort.Close();
        }
        catch (Exception cex)
        {
            //do logging
        }
        finally
        {
            try
            {
                localRefToPort.Dispose();
            }
            catch (Exception dex)
            {
                //do logging
            }
        }
    }
    catch (Exception ex)
    {
        //do logging
    }
}

Out of memory stacks I was able to get from UnhandledExceptionHandler.

Exception of type 'System.OutOfMemoryException' was thrown.
   at System.IO.Ports.SerialStream.EventLoopRunner.WaitForCommEvent()
   at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()

Next stack I got when I was reading from port. (code example above does not have it)

Exception of type 'System.OutOfMemoryException' was thrown.
   at Microsoft.Win32.Win32Native.CreateEvent(SECURITY_ATTRIBUTES lpSecurityAttributes, Boolean isManualReset, Boolean initialState, String name)
   at System.Threading.EventWaitHandle..ctor(Boolean initialState, EventResetMode mode, String name)
   at System.Threading.ManualResetEvent..ctor(Boolean initialState)
   at System.IO.Ports.SerialStream.BeginReadCore(Byte[] array, Int32 offset, Int32 numBytes, AsyncCallback userCallback, Object stateObject)
   at System.IO.Ports.SerialStream.ReadByte(Int32 timeout)
   at System.IO.Ports.SerialStream.ReadByte()
   at System.IO.Ports.SerialPort.ReadByte()
   at TestClass.SerialPortDataReceived(Object sender, SerialDataReceivedEventArgs e)

There is an article on MSDN that I suppose related to my problem. But I am not sure how I can apply suggested resolution. It is almost two weeks that I am fighting with this problem. I tried to detect device disconnection moment and close/dispose port as soon as possible but it did not help. Any suggestion is much appreciated.

Mike Znaet
  • 89
  • 10
  • My crystal ball says that you just jerked the connector without first clicking on the "Safely Remove Hardware" notification icon. Well, you now know what the unsafe kind looks like. – Hans Passant Oct 29 '14 at 18:03
  • @Hans Passant, you are right. But I cannot do "Safe Remove" in an environment where my application is working. – Mike Znaet Oct 29 '14 at 18:09
  • Nothing that can't be fixed with a little dab of super-glue. – Hans Passant Oct 29 '14 at 18:38
  • @HansPassant I looked, I hope, In all of similar questions and was not able to find an answer. People who talk about System.Threading.OverlappedData for the most part are tocking about sockets and not about serial ports. You can even close and delete my post. It is very frustrating when you fight with a problem for a long time without finding a solution and someone tels you..."This question has been asked before and already has an answer. " Where it this answer ? – Mike Znaet Oct 29 '14 at 18:55
  • Finally I've got my solution an a long story of research is finished. Even though my application is running on .Net v4.0, I installed .Netv4.5 on my client machines and I don't have memory leak any more. Hope this will help someone else. – Mike Znaet Oct 30 '14 at 13:51

0 Answers0