SOCKET句柄泄露帶來的內存災難


前些時候游戲莫名其妙出現大量內存泄露,我感到很詫異,當然一般情況下游戲的內存管理是極其嚴苛的,出現如此大量的內存泄露到底是怎么回事?

句柄濫用導致的內存泄露會多誇張呢,尤其SOCKET,在某些客戶端系統下,短短5個小時可以吃掉5GB以上內存,有甚者達到6GB,並且進程內存查看非常完好,並無激增,那內存去哪了?看看我們的排錯過程。

 

排錯過程:

1、首先我們第一反應還是內存泄露,但是觀察進程發現占用非常合理,並沒有絲毫的激增情況,甚至運行周期后還會出現下降的情況,此類情況用資源管理器和性能管理器可以進行排錯,從而進一步確定不是游戲本身所申請的內存泄露。

這里包含 MALLOC,NEW等方式。

為了安全期間,采用VLD進行內存泄露排錯,預計結果和我猜測的一樣,並無激增或泄露。

此處步驟必須,用於排除激增或可能存在激增的內存問題,在LINUX下有其他庫請自己查找,至於此地由於是客戶端泄露,采用的VLD庫用於內存泄露排錯。

2、其次我們發現是系統在申請並歸屬於該進程的一塊內存區域,就像共享內存一樣,此時已經初步認定為句柄未釋放導致的內存泄露,那么如何定位?

首先要讓內存產生泄露,然后請出PCHunter,啟動后找到游戲目標進程,右鍵查看進程句柄。

此時可以看到句柄數已經非常異常,數量高達1182個之多,有些進程甚至過萬,這是明顯的異常,除非一般的服務端進程,通常情況下句柄數不會達到如此之數。

然后要定位是什么句柄導致的系統內存激增,通過數量分析發現有一項神奇過多:

File \Device\Afd 0x00000B38 0xFFFFE0005183E070 30 32758

此處的 \Device\Afd  為關鍵,該類型代表為SOCKET句柄,此處已經徹底定位到原因,是SOCKET創建句柄但未釋放導致的異常。

3、以上方法已經定位到基本錯誤,確定是SOCKET,但是怎么知道是哪里呢,這就要監控所有SOCKET創建的地方,我這里是因為使用了第一個第三方的PING庫,而這個庫代碼只創建SOCKET不關閉SOCKET。

所以產生以上問題,簡單解決只要關閉不使用SOCKET即可解決,重點在於定位是異常難的,所以特寫此文。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM