針對于基于surging的dotnetty組件內存泄漏問題
一、概述
前段時間客戶碰到基于surging內存泄漏問題,邀請我來現場幫忙解決,對于dotnetty 我一直又愛又恨,因堆外內存DirectByteBufferChunk 中PoolChunk映射分配的16mb始終無法銷毀,后面設置優化了dotnetty 環境變量參數,未在同一線程下導致引用計數出現錯亂,從而導致的內存泄漏問題。

(木舟物聯網平臺:http://117.72.121.2:3100 用戶:fanly 用戶1:fanly12 密碼:123456
鏈路跟蹤Skywalking V8:http://117.72.121.2:8080/
surging 微服務引擎開源地址:https://github.com/fanliang11/surging(后面surging 會移動到microsurging進行維護)
二 、環境變量配置
我設置以下基于netty 的環境變量,
Environment.SetEnvironmentVariable("io.netty.allocator.maxOrder", "5");//調整 chunkSize 的大小,只能設置0-14范圍內的值,默認值11 Environment.SetEnvironmentVariable("io.netty.allocator.numDirectArenas", "0");// 設置Direct Arenas,默認核數*2 Environment.SetEnvironmentVariable("io.netty.allocator.type", "unpooled");// 不使用內存池 Environment.SetEnvironmentVariable("io.netty.allocator.numHeapArenas", "2");// 設置Heap Arenas,默認核數*2
在surging 代碼DotNettyModule的RegisterBuilder方法中添加,如下圖所示

三、ByteBuf 銷毀
surging 在ChannelHandlerAdapter 實例類已經把 ByteBuf進行銷毀,如下圖所示

四,ByteBuf分配處理銷毀
如果bytebuff分配處理銷毀處在不同線程下,會導致引用計數錯亂,導致無法銷毀,內存泄漏。在ChannelRead方法中不要開啟線程處理,比如Task.Run ,可以在pipeline中添加eventExecutor 進行處理,如下圖所示

五,Dump 分析結果
通過運行一天dump文件進行分析,已經未出現Chunk的16mb 內存。

六、通過鏈路跟蹤Skywalking 來監控是否出現內存性能問題




七、總結
因為身體問題,當中休息了一段時間,預估4月初MQTT會接入到木舟物聯網平臺,到時候會開放各個協議端口以便讓大家進行測試。
浙公網安備 33010602011771號