System.OutOfMemoryException' 是在晚上 10 点之后抛出的。我无法捕捉到实际错误

System.OutOfMemoryException' was thown after 10PM. I am not able to catch actual error

在服务器上安装了以下软件:

  1. Windows 服务器 2012,SQL 服务器
  2. 赛门铁克杀毒软件
  3. 指纹 reader 基于 Nginx,MS Sql 服务器数据库

我找不到错误。线程抛出错误 System.Outofmemory 并且服务器有 6GB 可用内存。一个socket最大接收数据小于4kb

class ServerModule
{
    TcpListener serverSocket;

    public void StartServer()
    {
        serverSocket.Start();
        while (true)
        {
            try
            {
                if (cmd == -1)
                {
                    break;// stop loop
                }
                Console.WriteLine("Listening");
                TcpClient tc= serverSocket.AcceptTcpClient();
                System.Threading.Thread obj_thread = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(ProcessData));
                obj_thread.Start(tc);
            }
            catch (Exception ex)
            {
                ErrorLogger.LogError("StartServer::", ex);
            }
        }
    }

    public void ProcessData(object ob)
    {
        TcpClient tcp_socket = (TcpClient)ob;
        NetworkStream ns = null;
        try
        {
            ns = tcp_socket.GetStream();
            int num = 0;
            byte[] obj_data = new byte[tcp_socket.ReceiveBufferSize];
            num = ns.Read(obj_data, 0, tcp_socket.ReceiveBufferSize);
            tcp_socket.Close();
            tcp_socket = null;
        }
        catch (Exception ex)
        {
            ErrorLogger.LogError("ProcessData::", data_from_device, ex);
            if (tcp_socket != null)
            {
                tcp_socket.Close();
                tcp_socket = null;
            }
            Console.WriteLine("Close with exception");
        }
    } 
}

您的代码抛出 OutOfMemoryException,因为其中创建了很多很多线程。看:

// in a infinite loop
while (true)
{
    ...
    // for each TcpClient
    TcpClient tc= serverSocket.AcceptTcpClient();
    // you create a thread!
    System.Threading.Thread obj_thread = new System.Threading.Thread
}

这是您可以在代码中做的最糟糕的事情。由于大量线程同时尝试侦听 TcpClients,您的应用程序饿死了。应用程序中建议的线程数等于服务器计算机上的内核数 (Managed Threading Best Practices)。

你真的应该使用一些线程池,你自己写的(我个人不推荐它)或者已经内置的(How to: Use a Thread Pool (C# and Visual Basic))。

如果您使用的是 .NET 4.5,请使用 Tasks library 来简化您的代码。
现在您的应用程序不稳定且容易出错。

如果出于某种原因您仍然认为每次调用 TcpClient 时都必须创建一个 Thread(我认为这是完全错误的),您应该阅读这篇文章手册:

How to: Create and Terminate Threads (C# Programming Guide)