1. 程式人生 > >設定Netty接收Buff為堆記憶體模式

設定Netty接收Buff為堆記憶體模式

轉自:https://sanwen8.cn/p/1bfoy1F.html

Netty為了提升報文的讀寫效能,預設會採用“零拷貝”模式,即訊息讀取時使用非堆的DirectBuffer來減少ByteBuffer的記憶體拷貝,如下圖所示:


如果需要修改接收Buffer的型別,例如從DirectByteBuf修改為HeapByteBuf,首先需要在初始化Channel的時候對接收緩衝區進行設定,客戶端程式碼示例如下:

 b.group(group)

.channel(NioSocketChannel.class)

 .option(ChannelOption.TCP_NODELAY, true)

 .option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)

 .option(ChannelOption.RCVBUF_ALLOCATOR, AdaptiveRecvByteBufAllocator.DEFAULT)

如果是服務端,則需要在鏈路建立之後,初始化時對Channel的SocketChannelConfig的Allocator屬性進行設定,程式碼如下:

.childHandler(new ChannelInitializer<SocketChannel>() {           

 @Override

  public void initChannel(SocketChannel ch) throws Exception {

  ch.config().setAllocator(UnpooledByteBufAllocator.DEFAULT);

無論是通過ChannelOption.RCVBUF_ALLOCATOR還是Allocator都只能設定Allocator的型別,無法直接設定ByteBufAllocator分配的ByteBuf型別。下面我們接著分析訊息讀取時的ByteBuf分配機制。訊息讀取時,呼叫的是NioByteUnsaferead方法,程式碼如下:


首先從SocketChannelConfig中獲取ByteBufAllocator,

在這裡就是UnpooledByteBufAllocator,然後呼叫它的ioBuffer方法分配記憶體,它的具體實現如下:

 @Override

    public ByteBuf ioBuffer() {

        if (PlatformDependent.hasUnsafe()) {

            return directBuffer(0);

        }

        return heapBuffer(0);

    }

如果非Unsafe模式,則會使用堆記憶體heapBuffer,接著看hasUnsafe方法實現,它最終會呼叫如下方法:


設定io.netty.noUnsafe屬性為true,則預設會使用Heap堆記憶體建立ByteBuf,下面我們在啟動時設定-Dio.netty.noUnsafe為true進行測試


設定完成之後,使用Echo程式進行測試,測試結果如下:

總結

利用ch.config().setAllocator或Bootstrap.option(ChannelOption.ALLOCATOR, ByteBufAllocator),結合-Dio.netty.noUnsafe,可以靈活的在如下四種ByteBuf之間進行切換:

  • UnpooledHeapByteBuf

  • PooledHeapByteBuf

  • UnpooledDirectByteBuf

  • PooledDirectByteBuf

相關推薦

設定Netty接收Buff記憶體模式

轉自:https://sanwen8.cn/p/1bfoy1F.html Netty為了提升報文的讀寫效能,預設會採用“零拷貝”模式,即訊息讀取時使用非堆的DirectBuffer來減少ByteBuffer的記憶體拷貝,如下圖所示: 如果需要修改接收Buffer的

CentOS 7 如何設定預設啟動方式命令列模式

作為Linux的初學者,參考文章的方法,安裝了一個GUI版的作業系統,以前只有最小安裝的命令列版本。 # yum groupinstall "GNOME Desktop" "Graphical Administration Tools" 安裝完之後,再啟動CentOS

深入淺出JVM(jvm記憶體結構,類載入器圖,雙親委託模式記憶體,GC解析,GC演算法)

目錄 Java虛擬機器的記憶體結構:  類載入器圖: 雙親委託模式: 堆記憶體: GC解析圖: GC演算法 Java虛擬機器的記憶體結構:  類載入器圖:   雙親委託模式: Java允許建立和JDK自帶類

設定樹莓派的無線網絡卡監聽模式(monitor)

先使用命令檢視無線網絡卡的名字: ifconfig 結果如下: eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.123.165 netmask 255.

VMware Linux SUSE 11 虛擬機器設定橋接模式設定靜態IP、使用Xshell連線虛擬機器的方法

一 設定橋接模式的方法 1.開啟VMware--編輯--虛擬網路編輯器   2.將VMnet0設定為橋接模式,橋接到……網絡卡選擇主機上網用的網絡卡。可以在 控制面板--網路和 Internet--網路連線中檢視   3.右鍵虛擬機器--設定

php錯誤處理,自動載入,以及棧記憶體和執行模式淺解 (轉)

Php錯誤處理 Php錯誤級別: E_ERROR 致命錯誤,會終止指令碼執行.值為1 E_WARNING 警告錯誤,給出提示,不會終止執行值為2 E_PARSE 編譯時的語法解析錯誤,解析錯誤僅僅由分析器產生。值為4 E_NOTICE 執行時通知錯誤,表示指令

C++巢狀類在單例模式Singleton中自動釋放記憶體的應用

首先放出單例模式中的程式碼: singleton.h #ifndef SINGLETON_H #define SINGLETON_H #include <iostream> #include

如何將MySQL GR 設定多主模式

在MySQL 5.7.17版本中釋出的MySQL Group Replication(後文簡稱為MGR)被很多人稱為MySQL複製方案的正規軍,可以一舉取代現在的MySQL Replication,Semisynchronous replication,甚至是可以取代之前最成功的MySQL叢集方案G

jvm 記憶體記憶體 大小設定

Tomcat 的JVM 記憶體溢位問題的解決關鍵字: tomcat 的jvm 記憶體溢位問題的解決  最近在熟悉一個開發了有幾年的專案,需要把資料庫從mysql移植到oracle,首先把jdbc的連線指向mysql,打包放到tomcat裡面,可以跑起來,沒有問題,可是當把jdbc連線指向oracle的時

《java performance》翻譯 第七章jvm調優:記憶體設定

    設定jvm堆記憶體     到目前為止,還沒有為調優jvm的記憶體佔用採取任何調優動作。下面這個步驟講述瞭如何來確定一個應用應該使用的jvm記憶體大小。這個步驟的目標是幫助調優人員找出應用的常駐記憶體大小,因為應用的常駐記憶體大小為配置應用的堆記憶體提供了很好的參考

JVM 記憶體設定原理

堆記憶體設定 原理 JVM堆記憶體分為2塊:Permanent Space 和 Heap Space。 Permanent 即 持久代(Permanent Generation),主要存放的是Java類定義資訊,與垃圾收集器要收集的Java物件關係不大。Heap = {

JVM記憶體設定

這個題目的答案選擇C,我在做這個題之前對於JVM的瞭解幾乎為0,所以看到這個題目基本就是隨便選了一個,甚至沒有看到原題中是持久區堆記憶體,只以為是記憶體溢位。所以在做完這個題目以後瞭解了一下JVM。JVM是指Java虛擬機器,JVM又分為了棧,堆,方法區,本地方法棧等幾個部分,因為這個題目的緣故,重點了解了下

CentOS7網絡卡設定橋接模式靜態IP配置方法詳解

備份網路檔案 [[email protected] network-scripts]# cd /etc/sysconfig/network-scripts/ [[email p

VMware下CentOS6.4網絡卡設定橋接模式靜態IP配置方法詳解

1、禁用網路管理器 # chkconfig NetworkManager off # service NetworkManager stop 2、建立用以橋接的虛擬網絡卡 # cd /etc/sysconfig/network-scripts # cp ifcf

Java記憶體Heap與非記憶體Non-Heap簡介和設定

Java 開發對JVM(Java虛擬機器)的瞭解很有必要,網上看到,收集整理轉載一下,方便日後的懶人計劃 堆(Heap)和非堆(Non-heap)記憶體   按照官方的說法:“Java 虛擬機器具有一個堆,堆是執行時資料區域,所有類例項和陣列的記憶體均從此處分配。堆是在

伺服器程式設計心得(四)—— 如何將socket設定非阻塞模式

1. windows平臺上無論利用socket()函式還是WSASocket()函式建立的socket都是阻塞模式的: SOCKET WSAAPI socket( _In_ int af, _In_ int type, _In_ int protocol )

socket設定非阻塞模式

1,套接字的預設狀態是阻塞的。即當發出一個不能立即完成的套接字呼叫時,該程序將被投入睡眠,等待相應操作完成。2,阻塞的套接字分為下面四類:輸入操作:包括read、recv、recvfrom和recvms

openfire 記憶體設定和如何設服務

問題1:   如何將openfire的服務設為啟動的服務? 解決方法:      openfire-service.exe      a:通過命令方式,啟動/關閉 (%openfire_home%/bin目錄下執行)         啟動 命令:           open

記憶體設定

年輕代所有新生成的物件首先都是放在年輕代。年輕代的目標就是儘可能快速的收集掉那些生命週期短的物件。年輕代一般分3個區,1個Eden區,2個Survivor區(from 和 to)。大部分物件在Eden區中生成。當Eden區滿時,還存活的物件將被複制到Survivor區(兩個中的一個),當一個Survivor區

SQL Server將資料庫設定單使用者模式

如何將SQL資料庫設定為單使用者模式:     SQL2000           普通資料庫,只需在企業管理器中,選擇資料庫屬性,惡訪問選項,但使用者即可;如果是Master Database,就需要一句查詢命令:           USE MASTER