使用Borland/Embarcadero TClientSocket
組件,我遇到了明顯的手柄泄漏。我有一個應用程序創建多個TThread
實例,每個實例動態創建一個TClientSocket
對象,連接到它的目標發送幾條消息,然後被刪除。然後刪除TThread
實例(使用FreeOnTerminate = true
)設置。我知道這是效率低下的,但它完全適合應用程序的需求 - 同時存在的最大數量限制爲32.我看到的問題是存在明顯的窗口句柄泄漏問題,我可以通過任務管理器查看。爲了解決這個問題,我在單線程意義上應用了相同的問題,只需動態創建一個對象並在主VCL線程的單個循環內完成時再次刪除它。這表現出相同的手柄泄漏問題。我知道該組件已被棄用,我知道我正在做的是低效率的,但我不明白爲什麼會出現句柄泄漏。在刪除這個句柄泄漏之前,有沒有什麼需要用TClientSocket
對象完成,或者這是組件中的錯誤?我在非阻塞模式下使用套接字並將事件處理程序分配到OnConnect
OnDisconnect
和OnSocketError
。使用多個TClientSocket實例導致Windows Handle泄漏的C++應用程序
回答
我已經使用了TClientSocket
多年,包括在主線程和工作線程中的使用情況,並且我從未見過TClientSocket
泄漏任何句柄。
然而,TClientSocket
不會默認爲非阻塞模式,在此模式下,使用AllocateHWnd()
創建一個隱藏的窗口接收套接字事件,並AllocateHWnd()
是不是線程安全。沒有看到您的實際代碼,這是您在工作線程代碼中看到的泄漏的可能原因。解決這個問題的方法就是不使用TClientSocket
在工作線程中使用時是非阻塞模式。改爲在阻塞模式下使用它。無論如何,它更適合基於線程的邏輯。
但是,這並不能解釋您在主線程代碼中看到的泄漏。我懷疑TClientSocket
實際上是罪魁禍首,再一次,沒有看到你的實際代碼,很難肯定地說。
感謝您的回覆。我只是看看Embarcadero的'AllocateHWnd()'文檔 - 根據你所說的話,這也意味着在線程中使用'TTimer'對象也是不安全的? – mathematician1975 2013-03-13 07:56:36
@ mathematician1975:是的,'TTimer'確實使用'AllocateHWnd()',所以'TTimer'在工作線程中也不安全。但是線程定時器有更好的選擇,比如'CreateWaitableTimer()'。 – 2013-03-13 16:42:15
感謝您的信息。我想我會重寫所有使用阻塞客戶端的東西。 – mathematician1975 2013-03-13 17:16:10
- 1. 跨應用程序實例泄漏?
- 2. 在UWP應用程序導航導致內存泄漏
- 3. Windows Phone多個應用程序實例
- 4. 如何泄漏上下文。 MyHandler的一個實例是否會導致泄漏?
- 5. gsoap內存泄漏C應用程序
- 6. 內存泄漏導致應用程序崩潰
- 7. 託管+非託管應用程序導致內存泄漏
- 8. 應用程序導致在泄漏工具崩潰
- 9. Appcelerator Studio - 由於內存泄漏導致應用程序崩潰
- 10. Dynamic Workload Console內存泄漏導致應用程序崩潰
- 11. 什麼樣的泄漏會導致WCF中TimeBoundedCache.ExpirableItem的實例泄漏?
- 12. 檢測C++ Windows應用程序中的內存泄漏
- 13. iOS應用程序泄漏
- 14. 從C#COM DLL到Delphi應用程序的回調導致內存泄漏
- 15. Linux上多線程C++應用程序中的內存泄漏
- 16. Windows通用應用程序的多個實例(Windows 10)
- 17. 使用jQuery.text()導致內存泄漏
- 18. 可以「使用」多個資源導致資源泄漏?
- 19. ObjectMapper SerializerCache的單個實例中的太多對象導致內存泄漏
- 20. MPMoviePlayerController導致泄漏
- 21. NSTimers導致泄漏
- 22. Visual C++,MFC應用程序,No Malloc等等:什麼會導致內存泄漏?
- 23. UITableView reloadData多次導致內存泄漏並減慢應用程序
- 24. 多線程應用程序和潛在內存泄漏(C#)
- 25. C++應用程序泄露與其他泄漏鏈接
- 26. 應用程序中的內存泄漏
- 27. 應用程序泄漏字符串?
- 28. Objective-C的ADDOBJECT導致內存泄漏
- 29. 內存泄漏時使用NSURLConnection實例
- 30. 使用c#XmlDocument加載多個xml文件導致內存泄漏
SO_LINGER也許?只是在這裏猜測。如果是這樣的話,我會感到驚訝,因爲這將是意想不到的,但是如果你能夠在底層套接字上獲得細粒度的控制,值得一提。 – WhozCraig 2013-03-12 21:33:31
@WhozCraig:'SO_LINGER'與手柄無關。但是,可以通過TClientSocket(通過'TClientSocket.Socket.SocketHandle'屬性)訪問底層的'SOCKET'句柄,並直接調用WinSock API函數,如'setsockopt()'。 – 2013-03-13 05:22:24
@RemyLebeau該插座後面是否沒有IO手柄?即,如果我打開10,000個套接字並啓動procexp,我*不會*看到處理計數比例?我只是提出它,因爲我有一個類似的問題與大容量快速卸載應用程序,這正是問題。在斷開連接之後,不會中斷計時器,手柄不會立即返回。正如我所說的,我遵循更多的知識,這看起來像你。謝謝(你的)信息。 – WhozCraig 2013-03-13 05:26:27