用netty实现zcool_Netty 如何玩转内存使用
內存使用技巧的目標
目標:
? 內存占用少(空間)
? 應用速度快(時間)
對 Java 而言:減少 Full GC 的 STW(Stop the world)時間
Netty 內存使用技巧 - 減少對像本身大小
例 1:用基本類型就不要用包裝類:
例 2: 應該定義成類變量的不要定義為實例變量:
? 一個類 -> 一個類變量
? 一個實例 -> 一個實例變量
? 一個類 -> 多個實例
? 實例越多,浪費越多。
例 3: Netty 中結合前兩者:
io.netty.channel.ChannelOutboundBuffer#incrementPendingOutboundBytes(long, boolean)
統計待寫的請求的字節數
AtomicLong -> volatile long + static AtomicLongFieldUpdater
Netty 內存使用技巧 - 對分配內存進行預估
例 1:對于已經可以預知固定 size 的 HashMap避免擴容
可以提前計算好初始size或者直接使用
com.google.common.collect.Maps#newHashMapWithExpectedSize
例 2:Netty 根據接受到的數據動態調整(guess)下個要分配的 Buffer 的大小??蓞⒖?/p>
io.netty.channel.AdaptiveRecvByteBufAllocator
Netty 內存使用技巧 - Zero-Copy
例 1:使用邏輯組合,代替實際復制。
例如 CompositeByteBuf:
io.netty.handler.codec.ByteToMessageDecoder#COMPOSITE_CUMULATOR
例 2:使用包裝,代替實際復制。
byte[] bytes = data.getBytes();
ByteBuf byteBuf = Unpooled.wrappedBuffer(bytes);
例 3:調用 JDK 的 Zero-Copy 接口。
Netty 中也通過在 DefaultFileRegion 中包裝了 NIO 的 FileChannel.transferTo() 方法實
現了零拷貝:io.netty.channel.DefaultFileRegion#transferTo
Netty 內存使用技巧 - 堆外內存
?JVM 內部 -> 堆(heap) + 非堆(non heap)
? JVM 外部 -> 堆外(off heap)
使用堆外內存 :
? 優點:
? 更廣闊的“空間 ”-> 破除堆空間限制,減輕 GC 壓力
? 減少“冗余”細節(假設燒烤過程為了氣氛在室外進行:烤好直接上桌:vs 烤好還
要進店內)-> 避免復制
? 缺點:
? 創建速度稍慢
? 堆外內存受操作系統管理
Netty 內存使用技巧 - 內存池
為什么引入對象池:
? 創建對象開銷大
? 對象高頻率創建且可復用
? 支持并發又能保護系統
? 維護、共享有限的資源
如何實現對象池?
? 開源實現:Apache Commons Pool
? Netty 輕量級對象池實現 io.netty.util.Recycler
怎么從堆外內存切換堆內使用?
? 方法 1:參數設置
io.netty.noPreferDirect = true;
? 方法 2:傳入構造參數false
ServerBootstrap serverBootStrap = new ServerBootstrap();
UnpooledByteBufAllocator unpooledByteBufAllocator = new UnpooledByteBufAllocator( false );
serverBootStrap.childOption(ChannelOption.ALLOCATOR, unpooledByteBufAllocator)
堆外內存的分配?
ByteBuffer.allocateDirect(initialCapacity)
總結
以上是生活随笔為你收集整理的用netty实现zcool_Netty 如何玩转内存使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 上海欢乐谷哪些项目好玩
- 下一篇: 字符串插入_计算机毕业设计中小程序插入h