我有一個用C#編寫的多線程TCP服務器。客戶端被服務器接受,並且在連接時不會離開服務器。經過大約1300次活動連接後,我的軟件出現System.OutOfMemmoryException錯誤。這個問題是否與32位系統架構和RAM有關?我有32位Windows 7專業版和4 GB內存。當我的服務器上存在大約1300個活動連接時,我的內存使用量約爲2.1GB,CPU使用率爲30%。TCP服務器中的C#System.OutOfMemmoryException
謝謝。
我有一個用C#編寫的多線程TCP服務器。客戶端被服務器接受,並且在連接時不會離開服務器。經過大約1300次活動連接後,我的軟件出現System.OutOfMemmoryException錯誤。這個問題是否與32位系統架構和RAM有關?我有32位Windows 7專業版和4 GB內存。當我的服務器上存在大約1300個活動連接時,我的內存使用量約爲2.1GB,CPU使用率爲30%。TCP服務器中的C#System.OutOfMemmoryException
謝謝。
System.OutOfMemmoryException
當您的進程中創建了~1300個線程時(在32位操作系統上)時拋出。問題是你正在爲每個連接創建全新的線程。這是不好的做法。
您應該改爲只使用一個線程來管理髮送數據,使用同一個線程(或可能是第二個)來發送數據,並且只能使用一個來接受連接。線程池接受所有客戶
代碼例如:一個線程接受所有客戶
TcpListener tcpListener = new TcpListener(IPAddress.Any, 90);
public void BeginAccept()
{
try { tcpListener.BeginAcceptTcpClient(AcceptClient, null); }
catch { /* Swallowing is bad */ }
}
private void AcceptClient(IAsyncResult ar)
{
TcpClient tcpClient;
try { tcpClient = tcpListener.EndAcceptTcpClient(ar); }
catch { /* Swallowing is bad */ }
finally { BeginAccept(); }
// TODO: Add your brand new tcpClient to some sort of collection, may be.
}
代碼示例:
TcpListener tcpListener = new TcpListener(IPAddress.Any, 90);
bool isListening;
public void BeginAccept()
{
while (isListening)
{
TcpClient tcpClient;
try { tcpClient = tcpListener.AcceptTcpClient(); }
catch { /* Swallowing is bad */ }
// TODO: Add your brand new tcpClient to some sort of collection, may be.
}
}
你應該看看貫徹Asynchronous Server Socket。
我仍然建議在不同的線程中發送響應以避免隊列/ TCP重發。
您可以使用任務,也可以將收到的消息與相關連接添加到併發隊列中,並由工作人員處理它們。
您的計算機/操作系統不是限制因素。它可以爲每個進程分配近4GB(如果總共使用4GB以上,它將開始交換/寫入磁盤:這比普通內存慢得多,但仍然可以工作)。 但是,C#編譯器正在限制您。 C#默認編譯32位,這意味着每個進程只能使用大約2GB的內存。這就是爲什麼你的服務器一旦達到2GB就會崩潰。 你可以編譯一個64位的操作系統,它可以讓你使用幾乎無限的內存,但是你沒有64位的操作系統,所以它不會在你的機器上運行。
最好爲每個客戶端連接而不是線程創建一個新進程。你的主進程會監聽和接受連接,當一個新的連接產生時,它應該產生一個專門用於處理與該客戶端的連接的新進程。因爲每個連接都有自己的進程,所以你不會再達到2GB的限制,並且還有很多優點:一旦連接關閉,回收內存就容易得多,並且一個連接中的任何錯誤都不太可能導致整個程序崩潰。 當然,多進程體系結構的編程比多線程編程要困難一些,因爲沒有共享內存,但這是更好的方法。
我猜...是的,無論如何,你的應用程序在32位體系結構上看不到超過2 GB的內存。 – 2012-04-12 12:06:47
你有一個線程每個連接或你使用線程池? – Nick 2012-04-12 12:08:14
我知道他有第一個。 – AgentFire 2012-04-12 12:11:09