System.OutOfMemoryException' 是在晚上 10 点之后抛出的。我无法捕捉到实际错误
System.OutOfMemoryException' was thown after 10PM. I am not able to catch actual error
在服务器上安装了以下软件:
- Windows 服务器 2012,SQL 服务器
- 赛门铁克杀毒软件
- 指纹 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
(我认为这是完全错误的),您应该阅读这篇文章手册:
在服务器上安装了以下软件:
- Windows 服务器 2012,SQL 服务器
- 赛门铁克杀毒软件
- 指纹 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
(我认为这是完全错误的),您应该阅读这篇文章手册: