1 降低物件大小
能用基本型別就不用包裝類
懂得都懂,
應該定義成類變數的不要定義為實體變數
- 一個類 =》 一個類變數
- 一個實體 =》一個實體變數
- 一個類 =》 多個實體
- 實體越多,浪費越多
當然 netty 會結合這兩點!

2 預估分配的記憶體
-
對已可預知固定size的HashMap避免擴容
提前計算好初始size或者直接使用
com.google.common.collect.Maps#newHashMapWithExpectedSize

-
根據接受到的資料動態調整(guess) 下個要分配的Buffer的大小,比如
io.netty.channel.AdaptiveRecvByteBufAllocator
3 零拷貝
邏輯組合代替實際復制
- CompositeByteBuf

包裝替代實際復制

JDK的零拷貝介面
Netty 通過在 DefaultFileRegion 包裝了 NIO 的 FileChannel.transferTo() 實作零拷貝:?о.nеttу.сhаnnеl.DеfаultF?lеRеg?оn#trаn?fеrТо

4 堆外記憶體
堆外記憶體生活場景:
燒烤店熱季時人滿為患,店家就會在門口加擺一些桌子招待新客人,
店內 =》 JVM內部 =》堆(heap) +非堆(non heap)
店外 =》 JVM外部 =》堆外(off heap)
優點
- 更廣闊的“空間”,緩解店鋪內壓力->破除堆空間限制,減輕GC壓力
- 減少“冗余”細節(燒烤程序是在室外進行的:烤好直接上桌 V.S 烤好還要
進店內) =》避免復制
缺點
- 需要搬桌子 =》創建速度稍慢
- 受城管監管、風險大 =》堆外記憶體受 os 管理
原始碼
- 堆外記憶體/堆內記憶體的默認選擇

- 切換方式

堆外記憶體的分配本質





- 可見依舊呼叫的 JDK 原生的堆外記憶體實作,

5 記憶體池
記憶體池生活場景:
點選單的演進
一張紙:一桌客人一張紙
點菜平板:回圈使用
為何使用記憶體池
- 創建物件開銷大
比如堆外記憶體就是這樣 - 物件高頻率創建且可復用
- 支持并發又能保護系統
- 維護、共享有限的資源
實作記憶體池
- 開源實作:Apache Commons Pool
程式共享,記憶體競爭較嚴重 - Netty輕量級物件池實作io.netty.util.Recycler
基于特定場景才創建
記憶體池/非記憶體池的配置切換




根據引數配置判定(切換方式二)

CSDN認證博客專家
CSDN博客專家
慕課網認證作者
騰訊云+最佳作者
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/240525.html
標籤:java
