『神坑』DotNetty 內存泄漏 解決辦法


背景

近來在用 DotNetty 實現一個文件上傳下載的同步服務。

其中:客戶端下載服務端的文件,客戶端多次請求,從服務端將文件分片下載下來,追加到本地磁盤。

—— 非常簡單的代碼,都寫了幾十次了,駕輕就熟。

問題來了

可是:在進行壓力測試時,我這邊下載一個 Win10 的 ISO 鏡像,4個G。

我發現:客戶端內存不停增長,直到內存溢出 —— 我擦。

VS2015內存診斷

內存診斷,我們發現 有很多 16M(16777228字節) 的 byte[] 占據着內存。

而我請求服務端的 文件分片 只有 64K

—— 於是我肯定:這些 16M 的 byte[] 肯定是 DotNetty 創建的。

調試代碼

通過調試代碼,確實發現了 這些 16M 字節所在的位置:

((DotNetty.Buffers.PooledByteBufferAllocator)
    ((DotNetty.Transport.Channels.AbstractChannelHandlerContext)context)
    .Allocator)
        .directArenas

簡寫就是:

context.Allocator.directArenas

知道了 內存泄漏 的數據 存在哪里,剩下的就是 刪除這些數據。

因為 AllocatordirectArenas 都是不可訪問的(私有類型)

我猜:按照微軟框架的習慣,肯定有 屬性 或 方法 能夠設置 這個東西。

—— 是我想太多,我找了好久 都找不到 相關方法。

萬能解法:反編譯

直到數據在哪里,肯定有修正這些數據的方法。

反射是萬能的 —— 但是我不想用。

於是,開始反編譯:查看這個 directArenas 字段在哪里 賦值、哪里添加數據。

問題解決

再次運行程序,內存穩定在 30M —— 內存泄漏問題解決。

這次修改BUG,最廢時間的 莫過於 DotNetty 毫無微軟風格。

微軟框架基本都有一個風格:底層一定提供了各種 函數、屬性 —— 默認會給你一個 最穩定的默認值。

尼瑪,這分明是 Java 的尿性:各種參數千奇百怪,不配參數還不能運行 —— 給我個默認參數 有那么難么~

 


免責聲明!

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



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