欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Netty核心功能之?dāng)?shù)據(jù)容器ByteBuf詳解

 更新時(shí)間:2022年10月21日 12:02:02   作者:ytKing  
這篇文章主要為大家介紹了Netty核心功能之?dāng)?shù)據(jù)容器ByteBuf詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

正文

網(wǎng)絡(luò)數(shù)據(jù)的基本單位總是字節(jié),Java NIO 提供了 ByteBuffer 作為它的字節(jié)容器,但是這個(gè)類(lèi)使用起來(lái)過(guò)于復(fù)雜,而且也有些繁瑣。 Netty 的 ByteBuffer 替代品是 ByteBuf,一個(gè)強(qiáng)大的實(shí)現(xiàn),既解決了 JDK API 的局限性,又為網(wǎng)絡(luò)應(yīng)用程序的開(kāi)發(fā)者提供了更好的 API。

1、簡(jiǎn)介

Netty 的數(shù)據(jù)處理 API 通過(guò)兩個(gè)組件暴露——abstract class ByteBufinterface ByteBufHolder,下面是一些 ByteBuf API 的優(yōu)點(diǎn):

  • 它可以被用戶(hù)自定義的緩沖區(qū)類(lèi)型擴(kuò)展;
  • 通過(guò)內(nèi)置的復(fù)合緩沖區(qū)類(lèi)型實(shí)現(xiàn)了透明的零拷貝;
  • 容量可以按需增長(zhǎng)(類(lèi)似于 JDK 的 StringBuilder);
  • 在讀和寫(xiě)這兩種模式之間切換不需要調(diào)用 ByteBuffer 的 flip()方法;
  • 讀和寫(xiě)使用了不同的索引;
  • 支持方法的鏈?zhǔn)秸{(diào)用;
  • 支持引用計(jì)數(shù);
  • 支持池化。

對(duì)比ByteBuffer的缺點(diǎn):

  • ByteBuffer長(zhǎng)度固定,一旦分配完成,它的容量不能動(dòng)態(tài)擴(kuò)展和收縮,當(dāng)需要編碼的POJO對(duì)象大于ByteBuffer的容量時(shí),會(huì)發(fā)生索引越界異常;
  • ByteBuffer只有一個(gè)標(biāo)識(shí)位置的指針position,讀寫(xiě)的時(shí)候需要手工調(diào)用flip()rewind()等,使用者必須小心謹(jǐn)慎地處理這些API,否則很容易導(dǎo)致程序處理失??;
  • ByteBuffer的API功能有限,一些高級(jí)和實(shí)用的特性它不支持,需要使用者自己編程實(shí)現(xiàn)。

2、ByteBuf 類(lèi)——Netty 的數(shù)據(jù)容器

所有的網(wǎng)絡(luò)通信都涉及字節(jié)序列的移動(dòng),所以高效易用的數(shù)據(jù)結(jié)構(gòu)明顯是必不可少的。所以理解Netty 的 ByteBuf 是如何滿(mǎn)足這些需求的很重要。

2.1 工作原理

ByteBuf工作機(jī)制:ByteBuf維護(hù)了兩個(gè)不同的索引,一個(gè)用于讀取,一個(gè)用于寫(xiě)入。readerIndexwriterIndex的初始值都是0,當(dāng)從ByteBuf中讀取數(shù)據(jù)時(shí),它的readerIndex將會(huì)被遞增(它不會(huì)超過(guò)writerIndex),當(dāng)向ByteBuf寫(xiě)入數(shù)據(jù)時(shí),它的writerIndex會(huì)遞增。

ByteBuf的幾個(gè)特點(diǎn):

  • 名稱(chēng)以readXXX或者writeXXX開(kāi)頭的ByteBuf方法,會(huì)推進(jìn)對(duì)應(yīng)的索引,而以setXXXgetXXX開(kāi)頭的操作不會(huì)。
  • 在讀取之后,0~readerIndex的就被視為discard的,調(diào)用discardReadBytes方法,可以釋放這部分空間,它的作用類(lèi)似ByteBuffercompact()方法。
  • readerIndexwriterIndex之間的數(shù)據(jù)是可讀取的,等價(jià)于ByteBufferpositionlimit之間的數(shù)據(jù)。writerIndexcapacity之間的空間是可寫(xiě)的,等價(jià)于ByteBufferlimitcapacity之間的可用空間。

2.2 ByteBuf的三種類(lèi)型

堆緩沖區(qū)

最常用的 ByteBuf 模式是將數(shù)據(jù)存儲(chǔ)在 JVM 的堆空間中。這種模式被稱(chēng)為支撐數(shù)組(backing array),它能在沒(méi)有使用池化的情況下提供快速的分配和釋放

優(yōu)點(diǎn):由于數(shù)據(jù)存儲(chǔ)在JVM的堆中可以快速創(chuàng)建和快速釋放,并且提供了數(shù)組的直接快速訪(fǎng)問(wèn)的方法。

缺點(diǎn):每次讀寫(xiě)數(shù)據(jù)都要先將數(shù)據(jù)拷貝到直接緩沖區(qū)(相關(guān)閱讀:Java NIO 直接緩沖區(qū)和非直接緩沖區(qū)對(duì)比)再進(jìn)行傳遞。

示例:

// 創(chuàng)建一個(gè)堆緩沖區(qū)
ByteBuf buffer = Unpooled.buffer(10);
String s = "waylau";
buffer.writeBytes(s.getBytes());
// 檢查是否是支撐數(shù)組
if (buffer.hasArray()) {
  // 獲取支撐數(shù)組的引用
  byte[] array = buffer.array();
  // 計(jì)算第一個(gè)字節(jié)的偏移量
  int offset = buffer.readerIndex() + buffer.arrayOffset();
  // 可讀字節(jié)數(shù)
  int length = buffer.readableBytes();
  // 使用數(shù)組、偏移量和長(zhǎng)度作為參數(shù)調(diào)用自定義的使用方法
  printBuffer(array, offset, length);
}
/**
  * 打印出Buffer的信息
  * 
  * @param buffer
  */
private static void printBuffer(byte[] array, int offset, int len) {
  System.out.println("array:" + array);
  System.out.println("array->String:" + new String(array));
  System.out.println("offset:" + offset);
  System.out.println("len:" + len);
}
/**
輸出結(jié)果:
array:[B@5b37e0d2
array->String:waylau    
offset:0
len:6
*/

直接緩沖區(qū)

Direct Buffer在堆之外直接分配內(nèi)存,直接緩沖區(qū)不會(huì)占用堆的容量。

優(yōu)點(diǎn):在使用Socket傳遞數(shù)據(jù)時(shí)性能很好,由于數(shù)據(jù)直接在內(nèi)存中,不存在從JVM拷貝數(shù)據(jù)到直接緩沖區(qū)的過(guò)程,性能好。

缺點(diǎn):因?yàn)镈irect Buffer是直接在內(nèi)存中,所以分配內(nèi)存空間和釋放內(nèi)存比堆緩沖區(qū)更復(fù)雜和慢。

示例:

// 創(chuàng)建一個(gè)直接緩沖區(qū)
ByteBuf buffer = Unpooled.directBuffer(10);
String s = "waylau";
buffer.writeBytes(s.getBytes());
// 檢查是否是支撐數(shù)組.
// 不是支撐數(shù)組,則為直接緩沖區(qū)
if (!buffer.hasArray()) {
  // 計(jì)算第一個(gè)字節(jié)的偏移量
  int offset = buffer.readerIndex();
  // 可讀字節(jié)數(shù)
  int length = buffer.readableBytes();
  // 獲取字節(jié)內(nèi)容
  byte[] array = new byte[length];
  buffer.getBytes(offset, array);
  // 使用數(shù)組、偏移量和長(zhǎng)度作為參數(shù)調(diào)用自定義的使用方法
  printBuffer(array, offset, length);
}
/**
  * 打印出Buffer的信息
  * 
  * @param buffer
  */
private static void printBuffer(byte[] array, int offset, int len) {
  System.out.println("array:" + array);
  System.out.println("array->String:" + new String(array));
  System.out.println("offset:" + offset);
  System.out.println("len:" + len);
}
/**
輸出結(jié)果:
array:[B@6d5380c2
array->String:waylau
offset:0
len:6
*/

復(fù)合緩沖區(qū)

復(fù)合緩沖區(qū)是 Netty 特有的緩沖區(qū)。本質(zhì)上類(lèi)似于提供一個(gè)或多個(gè) ByteBuf 的組合視圖,可以根據(jù)需要添加和刪除不同類(lèi)型的 ByteBuf

優(yōu)點(diǎn):提供了一種訪(fǎng)問(wèn)方式讓使用者自由地組合多個(gè)ByteBuf,避免了復(fù)制和分配新的緩沖區(qū)。

缺點(diǎn):不支持訪(fǎng)問(wèn)其支撐數(shù)組。因此如果要訪(fǎng)問(wèn),需要先將內(nèi)容復(fù)制到堆內(nèi)存中,再進(jìn)行訪(fǎng)問(wèn)。

示例:

// 創(chuàng)建一個(gè)堆緩沖區(qū)
ByteBuf heapBuf = Unpooled.buffer(3);
String way = "way";
heapBuf.writeBytes(way.getBytes());
// 創(chuàng)建一個(gè)直接緩沖區(qū)
ByteBuf directBuf = Unpooled.directBuffer(3);
String lau = "lau";
directBuf.writeBytes(lau.getBytes());
// 創(chuàng)建一個(gè)復(fù)合緩沖區(qū)
CompositeByteBuf compositeBuffer = Unpooled.compositeBuffer(10);
compositeBuffer.addComponents(heapBuf, directBuf); // 將緩沖區(qū)添加到符合緩沖區(qū)
// 檢查是否是支撐數(shù)組.
// 不是支撐數(shù)組,則為復(fù)合緩沖區(qū)
if (!compositeBuffer.hasArray()) {
  for (ByteBuf buffer : compositeBuffer) {
    // 計(jì)算第一個(gè)字節(jié)的偏移量
    int offset = buffer.readerIndex();
    // 可讀字節(jié)數(shù)
    int length = buffer.readableBytes();
    // 獲取字節(jié)內(nèi)容
    byte[] array = new byte[length];
    buffer.getBytes(offset, array);
    // 使用數(shù)組、偏移量和長(zhǎng)度作為參數(shù)調(diào)用自定義的使用方法
    printBuffer(array, offset, length);
  }
}
/**
  * 打印出Buffer的信息
  * 
  * @param buffer
  */
private static void printBuffer(byte[] array, int offset, int len) {
  System.out.println("array:" + array);
  System.out.println("array->String:" + new String(array));
  System.out.println("offset:" + offset);
  System.out.println("len:" + len);
}
/**
輸出結(jié)果:
array:[B@4d76f3f8
array->String:way
offset:0
len:3
array:[B@2d8e6db6
array->String:lau
offset:0
len:3
*/

3、字節(jié)級(jí)操作

ByteBuf 提供了許多超出基本讀、寫(xiě)操作的方法用于修改它的數(shù)據(jù)。

3.1 隨機(jī)訪(fǎng)問(wèn)索引和順序訪(fǎng)問(wèn)索引

如同在普通的 Java 字節(jié)數(shù)組中一樣,ByteBuf 的索引是從零開(kāi)始的:第一個(gè)字節(jié)的索引是 0,最后一個(gè)字節(jié)的索引總是 數(shù)組容量 - 1。在ByteBuf的實(shí)現(xiàn)類(lèi)中都有一個(gè)方法可以快速獲得容量值,那就是capacity()。有了這個(gè)capcity()方法,我們就能很簡(jiǎn)單的實(shí)現(xiàn)隨機(jī)訪(fǎng)問(wèn)索引:

for (int i = 0;i<buf.capacity();i++){
    char b = (char)buf.getByte(i);//通過(guò) getBytes 系列接口來(lái)對(duì)ByteBuf進(jìn)行隨機(jī)訪(fǎng)問(wèn)。
    System.out.println(b);
}

Tips: 用getBytes隨機(jī)訪(fǎng)問(wèn)不會(huì)改變r(jià)eaderIndex

通過(guò) readerIndex()writerIndex() 獲取讀Index和寫(xiě)Index。

3.2 可丟棄字節(jié)

在上圖中標(biāo)記為可丟棄字節(jié)的分段包含了已經(jīng)被讀過(guò)的字節(jié)。通過(guò)調(diào)用 discardReadBytes()方法,可以丟棄它們并回收空間。這個(gè)分段的初始大小為 0,存儲(chǔ)在 readerIndex 中, 會(huì)隨著 read 操作的執(zhí)行而增加(get操作不會(huì)移動(dòng) readerIndex)。

下圖展示了在上圖的緩沖區(qū)上調(diào)用discardReadBytes()方法后的結(jié)果,需要注意的是丟棄并不是字節(jié)把已經(jīng)讀的字段的字節(jié)不要了,而是把尚未讀的字節(jié)數(shù)移到最開(kāi)始。(這樣做對(duì)可寫(xiě)分段的內(nèi)容并沒(méi)有任何的保證,因?yàn)橹皇且苿?dòng)了可以讀取的字節(jié)以及 writerIndex,而沒(méi)有對(duì)所有可寫(xiě)入的字節(jié)進(jìn)行擦除寫(xiě))

3.3 可讀字節(jié)

ByteBuf 的可讀字節(jié)分段存儲(chǔ)了實(shí)際數(shù)據(jù)。新分配的、包裝的或者復(fù)制的緩沖區(qū)的默認(rèn)的 readerIndex 值為 0。任何名稱(chēng)以 read 或者 skip 開(kāi)頭的操作都將檢索或者跳過(guò)位于當(dāng)前 readerIndex 之前的數(shù)據(jù),并且在readerIndex 的基礎(chǔ)上增加已讀字節(jié)數(shù)。 如果被調(diào)用的方法需要一個(gè) ByteBuf 參數(shù)作為寫(xiě)入的目標(biāo),并且沒(méi)有指定目標(biāo)索引參數(shù), 那么該目標(biāo)緩沖區(qū)的 writerIndex 也將被增加。

3.4 可寫(xiě)字節(jié)

可寫(xiě)字節(jié)分段是指一個(gè)擁有未定義內(nèi)容的、寫(xiě)入就緒的內(nèi)存區(qū)域。新分配的緩沖區(qū)的 writerIndex 的默認(rèn)值為 0。任何名稱(chēng)以 write 開(kāi)頭的操作都將從當(dāng)前的 writerIndex 處 開(kāi)始寫(xiě)數(shù)據(jù),并且在writerIndex 的基礎(chǔ)上增加已寫(xiě)字節(jié)數(shù)。如果寫(xiě)操作的目標(biāo)也是 ByteBuf,并且沒(méi)有指定 源索引的值,則源緩沖區(qū)的 readerIndex 也同樣會(huì)被增加相同的大小。

3.5 索引管理

JDK 的 InputStream 定義了 mark(int readlimit)reset()方法,這些方法分別 被用來(lái)將流中的當(dāng)前位置標(biāo)記為指定的值,以及將流重置到該位置。

同樣,可以通過(guò)調(diào)用 markReaderIndex()、markWriterIndex()、resetWriterIndex()resetReaderIndex()來(lái)標(biāo)記和重置 ByteBufreaderIndexwriterIndex。這些和 InputStream 上的調(diào)用類(lèi)似,只是沒(méi)有 readlimit 參數(shù)來(lái)指定標(biāo)記什么時(shí)候失效

也可以通過(guò)調(diào)用 readerIndex(int)或者 writerIndex(int)來(lái)將索引移動(dòng)到指定位置。試 圖將任何一個(gè)索引設(shè)置到一個(gè)無(wú)效的位置都將導(dǎo)致一個(gè) IndexOutOfBoundsException。

可以通過(guò)調(diào)用 clear()方法來(lái)將 readerIndexwriterIndex 都設(shè)置為 0。注意,這 并不會(huì)清除內(nèi)存中的內(nèi)容。調(diào)用后的存儲(chǔ)結(jié)構(gòu)如下圖所示:

調(diào)用 clear()比調(diào)用 discardReadBytes()輕量得多,因?yàn)樗鼘⒅皇侵刂盟饕粫?huì)復(fù) 制任何的內(nèi)存

3.6 派生緩沖區(qū)

派生緩沖區(qū)為 ByteBuf 提供了以專(zhuān)門(mén)的方式來(lái)呈現(xiàn)其內(nèi)容的視圖。這類(lèi)視圖是通過(guò)以下方法被創(chuàng)建的:

  • duplicate();
  • slice();
  • slice(int, int);
  • Unpooled.unmodifiableBuffer(…);
  • order(ByteOrder);
  • readSlice(int)。

每個(gè)這些方法都將返回一個(gè)新的 ByteBuf 實(shí)例,它具有自己的讀索引、寫(xiě)索引和標(biāo)記 索引。其內(nèi)部存儲(chǔ)和 JDK 的 ByteBuffer 一樣也是共享的。這使得派生緩沖區(qū)的創(chuàng)建成本是很低廉的,但是這也意味著,如果你修改了它的內(nèi)容,也同時(shí)修改了其對(duì)應(yīng)的源實(shí)例,所以要小心。

ByteBuf 復(fù)制 如果需要一個(gè)現(xiàn)有緩沖區(qū)的真實(shí)副本,請(qǐng)使用 copy()或者 copy(int, int)方 法。不同于派生緩沖區(qū),由這個(gè)調(diào)用所返回的 ByteBuf 擁有獨(dú)立的數(shù)據(jù)副本。

3.7 讀/寫(xiě)操作

有兩種類(lèi)別的讀/寫(xiě)操作:

  • get()和 set()操作,從給定的索引開(kāi)始,并且保持索引不變;
  • read()和 write()操作,從給定的索引開(kāi)始,并且會(huì)根據(jù)已經(jīng)訪(fǎng)問(wèn)過(guò)的字節(jié)數(shù)對(duì)索引進(jìn)行調(diào)整。

常用的 get()方法如下圖:

常用的 set()方法如下圖:

常用的 read()方法如下圖:

常用的 write()方法如下圖:

4、ByteBufHolder 接口

4.1 按需分配:ByteBufAllocator 接口

Netty 中內(nèi)存分配有一個(gè)最頂層的抽象就是ByteBufAllocator,負(fù)責(zé)分配所有ByteBuf 類(lèi)型的內(nèi)存。他的一些操作如下:

可以通過(guò) Channel(每個(gè)都可以有一個(gè)不同的 ByteBufAllocator 實(shí)例)或者綁定到 ChannelHandlerChannelHandlerContext 獲取一個(gè)到 ByteBufAllocator 的引用,如下圖所示:

Netty提供了兩種ByteBufAllocator的實(shí)現(xiàn):PooledByteBufAllocatorUnpooledByteBufAllocator。前者池化了ByteBuf的實(shí)例以提高性能并最大限度地減少內(nèi)存碎片,這是通過(guò)一種 叫做jemalloc的方法來(lái)分配內(nèi)存的(閱讀資料:jemalloc剖析)。后者的實(shí)現(xiàn)不池化ByteBuf實(shí)例,并且在每次它被調(diào)用時(shí)都會(huì)返回一個(gè)新的實(shí)例。

4.2 Unpooled 緩沖區(qū)

可能某些情況下,你未能獲取一個(gè)到 ByteBufAllocator 的引用。對(duì)于這種情況,Netty 提 供了一個(gè)簡(jiǎn)單的稱(chēng)為 Unpooled 的工具類(lèi),它提供了靜態(tài)的輔助方法來(lái)創(chuàng)建未池化的 ByteBuf 實(shí)例。他的一些操作如下:

4.3 ByteBufUtil 類(lèi)

ByteBufUtil 提供了用于操作 ByteBuf 的靜態(tài)的輔助方法。這個(gè) API 是通用的,并且和池化無(wú)關(guān)。

5、引用計(jì)數(shù)

引用計(jì)數(shù)是一種通過(guò)在某個(gè)對(duì)象所持有的資源不再被其他對(duì)象引用時(shí)釋放該對(duì)象所持有的資源來(lái)優(yōu)化內(nèi)存使用和性能的技術(shù)。Netty 在第 4 版中為 ByteBufByteBufHolder 引入了 引用計(jì)數(shù)技術(shù),它們都實(shí)現(xiàn)了 interface ReferenceCounted。

5.1 基本原理

一個(gè)新創(chuàng)建的引用計(jì)數(shù)對(duì)象的初始引用計(jì)數(shù)是1。

ByteBuf buf = ctx.alloc().directbuffer();
assert buf.refCnt() == 1;

當(dāng)你釋放掉引用計(jì)數(shù)對(duì)象,它的引用次數(shù)減1.如果一個(gè)對(duì)象的引用計(jì)數(shù)到達(dá)0,該對(duì)象就會(huì)被釋放或者歸還到創(chuàng)建它的對(duì)象池。

assert buf.refCnt() == 1;
// release() returns true only if the reference count becomes 0.
boolean destroyed = buf.release();
assert destroyed;
assert buf.refCnt() == 0;

訪(fǎng)問(wèn)引用計(jì)數(shù)為0的引用計(jì)數(shù)對(duì)象會(huì)觸發(fā)一次IllegalReferenceCountException。

assert buf.refCnt() == 0;
try {
buf.writeLong(0xdeadbeef);
throw new Error("should not reach here");
} catch (IllegalReferenceCountExeception e) {
// Expected
}

只要引用計(jì)數(shù)對(duì)象未被銷(xiāo)毀,就可以通過(guò)調(diào)用retain()方法來(lái)增加引用次數(shù)。

ByteBuf buf = ctx.alloc().directBuffer();
assert buf.refCnt() == 1;
buf.retain();
assert buf.refCnt() == 2;
boolean destroyed = buf.release();
assert !destroyed;
assert buf.refCnt() == 1;

5.2 誰(shuí)來(lái)銷(xiāo)毀

一般的原則是,最后訪(fǎng)問(wèn)引用計(jì)數(shù)對(duì)象的部分負(fù)責(zé)對(duì)象的銷(xiāo)毀。更具體地來(lái)說(shuō):

  • 如果一個(gè)[發(fā)送]組件要傳遞一個(gè)引用計(jì)數(shù)對(duì)象到另一個(gè)[接收]組件,發(fā)送組件通常不需要 負(fù)責(zé)去銷(xiāo)毀對(duì)象,而是將這個(gè)銷(xiāo)毀的任務(wù)推延到接收組件
  • 如果一個(gè)組件消費(fèi)了一個(gè)引用計(jì)數(shù)對(duì)象,并且不知道誰(shuí)會(huì)再訪(fǎng)問(wèn)它(例如,不會(huì)再將引用 發(fā)送到另一個(gè)組件),那么,這個(gè)組件負(fù)責(zé)銷(xiāo)毀工作。

5.3 內(nèi)存泄漏問(wèn)題

引用計(jì)數(shù)的缺點(diǎn)是,引用計(jì)數(shù)對(duì)象容易發(fā)生泄露。因?yàn)镴VM并不知道Netty的引用計(jì)數(shù)實(shí)現(xiàn),當(dāng)引用計(jì)數(shù)對(duì)象不 可達(dá)時(shí),JVM就會(huì)將它們GC掉,即時(shí)此時(shí)它們的引用計(jì)數(shù)并不為0。一旦對(duì)象被GC就不能再訪(fǎng)問(wèn),也就不能歸還到緩沖池,所以會(huì)導(dǎo)致內(nèi)存泄露。 慶幸的是,盡管發(fā)現(xiàn)內(nèi)存泄露很難,但是Netty會(huì)對(duì)分配的緩沖區(qū)的1%進(jìn)行采樣,來(lái)檢查你的應(yīng)用中是否存在內(nèi)存泄露。

內(nèi)存泄露檢查等級(jí)

總共有4個(gè)內(nèi)存泄露檢查等級(jí):

  • DISABLED – 完全禁用檢查。不推薦。
  • SIMPLE – 檢查1%的緩沖區(qū)是否存在內(nèi)存泄露。默認(rèn)。
  • ADVANCED – 檢查1%的緩沖區(qū),并提示發(fā)生內(nèi)存泄露的位置
  • PARANOID – 與ADVANCED等級(jí)一樣,不同的是會(huì)檢查所有的緩沖區(qū)。對(duì)于自動(dòng)化測(cè)試很有用,你可以讓構(gòu)建測(cè)試失敗 如果構(gòu)建輸出中包含’LEAK’ 用JVM選項(xiàng) -Dio.netty.leakDetectionLevel 來(lái)指定內(nèi)存泄露檢查等級(jí)

避免泄露最佳實(shí)踐

  • 指定SIMPLE和PARANOI等級(jí),運(yùn)行單元測(cè)試和集成測(cè)試
  • 在將你的應(yīng)用部署到整個(gè)集群前,盡可能地用足夠長(zhǎng)的時(shí)間,使用SIMPLE級(jí)別去調(diào)試你的程序,來(lái)看是否存在內(nèi)存泄露
  • 如果存在內(nèi)存泄露,使用ADVANCED級(jí)別去調(diào)試程序,去獲取內(nèi)存泄漏的位置信息
  • 不要將存在內(nèi)存泄漏的應(yīng)用部署到整個(gè)集群

以上就是Netty核心功能之?dāng)?shù)據(jù)容器ByteBuf詳解的詳細(xì)內(nèi)容,更多關(guān)于Netty 數(shù)據(jù)容器ByteBuf的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • java數(shù)組輸出的實(shí)例代碼

    java數(shù)組輸出的實(shí)例代碼

    這篇文章主要介紹了java數(shù)組輸出的實(shí)例代碼,有需要的朋友可以參考一下
    2013-12-12
  • springboot2.0+elasticsearch5.5+rabbitmq搭建搜索服務(wù)的坑

    springboot2.0+elasticsearch5.5+rabbitmq搭建搜索服務(wù)的坑

    這篇文章主要介紹了springboot2.0+elasticsearch5.5+rabbitmq搭建搜索服務(wù)的坑,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-06-06
  • JPA?CriteriaBuilder子查詢(xún)方式

    JPA?CriteriaBuilder子查詢(xún)方式

    這篇文章主要介紹了JPA?CriteriaBuilder子查詢(xún)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • java程序員自己的圖片轉(zhuǎn)文字OCR識(shí)圖工具分享

    java程序員自己的圖片轉(zhuǎn)文字OCR識(shí)圖工具分享

    這篇文章主要介紹了java程序員自己的圖片轉(zhuǎn)文字OCR識(shí)圖工具,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • Springboot mybatisplus如何解決分頁(yè)組件IPage失效問(wèn)題

    Springboot mybatisplus如何解決分頁(yè)組件IPage失效問(wèn)題

    這篇文章主要介紹了Springboot mybatisplus如何解決分頁(yè)組件IPage失效問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • Java使用組合模式實(shí)現(xiàn)表示公司組織結(jié)構(gòu)功能示例

    Java使用組合模式實(shí)現(xiàn)表示公司組織結(jié)構(gòu)功能示例

    這篇文章主要介紹了Java使用組合模式實(shí)現(xiàn)表示公司組織結(jié)構(gòu)功能,簡(jiǎn)單描述了組合模式的概念、功能并結(jié)合實(shí)例形式分析了Java使用組合模式實(shí)現(xiàn)公司組織結(jié)構(gòu)表示功能具體操作步驟與相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2018-05-05
  • 解決JDK版本沖突顯示問(wèn)題(雙版本沖突)

    解決JDK版本沖突顯示問(wèn)題(雙版本沖突)

    這篇文章主要介紹了解決JDK版本沖突顯示問(wèn)題(雙版本沖突),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • springboot配置nacos的實(shí)現(xiàn)示例

    springboot配置nacos的實(shí)現(xiàn)示例

    本文將介紹如何在Spring?Boot中配置Nacos,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-09-09
  • spring-security關(guān)閉登錄框的實(shí)現(xiàn)示例

    spring-security關(guān)閉登錄框的實(shí)現(xiàn)示例

    這篇文章主要介紹了spring-security關(guān)閉登錄框的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05
  • java_IO向文件中寫(xiě)入和讀取內(nèi)容代碼實(shí)例

    java_IO向文件中寫(xiě)入和讀取內(nèi)容代碼實(shí)例

    這篇文章主要介紹了java_IO向文件中寫(xiě)入和讀取內(nèi)容,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03

最新評(píng)論