日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Netty的引用计数对象

發布時間:2025/3/15 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Netty的引用计数对象 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

從Netty 4起,對象的生命周期由它們的引用計數來管理,因此,一旦對象不再被引用后,Netty 會將它(或它共享的資源)歸還到對象池(或對象分配器)。在垃圾回收和引用隊列不能保證這么有效、實時的不可達性檢測的情況下,引用計數以犧牲輕微的便利性為代價,提供了另一種可選的解決方案。 最值得注意的類型是ByteBuf,它正是利用了引用計數來提升內存分配和釋放的性能。

一、引用計數基本原理

一個新創建的引用計數對象的初始引用計數是1。

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

當你釋放掉引用計數對象,它的引用次數減1.如果一個對象的引用計數到達0,該對象就會被 釋放或者歸還到創建它的對象池。

assert buf.refCnt() == 1; // release() returns true only if the reference count becomes 0. boolean destroyed = buf.release(); assert destroyed; assert buf.refCnt() == 0;
  • 懸掛引用
  • 訪問引用計數為0的引用計數對象會觸發一次IllegalReferenceCountException:

    assert buf.refCnt() == 0; try { buf.writeLong(0xdeadbeef); throw new Error("should not reach here"); } catch (IllegalReferenceCountExeception e) { // Expected }
  • 增加引用計數
  • 只要引用計數對象未被銷毀,就可以通過調用retain()方法來增加引用次數:

    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;
  • 誰來銷毀
    一般的原則是,最后訪問引用計數對象的部分負責對象的銷毀。更具體地來說:
    • 如果一個[發送]組件要傳遞一個引用計數對象到另一個[接收]組件,發送組件通常不需要 負責去銷毀對象,而是將這個銷毀的任務推延到接收組件
    • 如果一個組件消費了一個引用計數對象,并且不知道誰會再訪問它(例如,不會再將引用 發送到另一個組件),那么,這個組件負責銷毀工作
      這里有一個簡單的示例:
    public ByteBuf a(ByteBuf input) {input.writeByte(42);return input; } public ByteBuf b(ByteBuf input) {try {output = input.alloc().directBuffer(input.readableBytes() + 1);output.writeBytes(input);output.writeByte(42);return output;} finally {input.release();} } public void c(ByteBuf input) {System.out.println(input);input.release(); } public void main() {...ByteBuf buf = ...;// This will print buf to System.out and destroy it.c(b(a(buf)));assert buf.refCnt() == 0; }

    二、子緩沖區(Derived buffers)

    調用ByteBuf.duplicate(),ByteBuf.slice()和ByteBuf.order(ByteOrder)三個方法, 會創建一個子緩沖區,子緩沖區共享父緩沖區的內存區域。子緩沖區沒有自己的引用計數,而是共享父緩沖區的引用計數。

    ByteBuf parent = ctx.alloc().directBuffer(); ByteBuf derived = parent.duplicate(); // Creating a derived buffer does not increase the reference count. assert parent.refCnt() == 1; assert derived.refCnt() == 1;

    但是,調用ByteBuf.copy()和ByteBuf.readBytes(int)創建的并不是子緩沖區,返回的 ByteBuf緩沖區是需要被釋放的。 需要注意,父緩沖區和它的子緩沖區共享引用計數,創建子緩沖區并不會增加引用計數。 因此,當你將子緩沖區傳到應用中的其他組件,必須先調用retain()。

    ByteBuf parent = ctx.alloc().directBuffer(512); parent.writeBytes(...); try {while (parent.isReadable(16)) {ByteBuf derived = parent.readSlice(16);derived.retain();process(derived);} } finally {parent.release(); } ... public void process(ByteBuf buf) {...buf.release(); }
  • ByteBufHolder接口
    有時候,ByteBuf被緩沖區容器(buffer holder)持有,像DatagramPacket、HttpComponent和WebSocketFrame。 這些類型都繼承自一個通用接口,叫做ByteBufHolder。 緩沖區容器(buffer holder)共享它持有的緩沖區的引用計數,和子緩沖區一樣。

  • Channel-handler中的引用計數

    • 入口消息

    當一個事件循環(event loop)讀取數據并寫入到ByteBuf,在觸發一次channelRead()事件后,應該由對應pipeline的 ChannelHandler負責去釋放緩沖區的內存。因此,消費接收數據的handler應該在它channelRead()方法中調用數據的 release()方法。

    public void channelRead(ChannelHandlerContext ctx, Object msg) {ByteBuf buf = (ByteBuf) msg;try {...} finally {buf.release();}}

    在“誰負責銷毀”一節中我們提到,如果你的handler將緩沖區(或者其他任何引用計數對象)傳遞到下一個handler, 那么你不需要負責去釋放。

    public void channelRead(ChannelHandlerContext ctx, Object msg) {ByteBuf buf = (ByteBuf) msg;...ctx.fireChannelRead(buf); }

    需要注意的是,ByteBuf并不是Netty中唯一的引用計數類型。如果你在與解碼程序(decoder)生成的消息打交道,這些消息一樣可能 是引用計數的。

    / Assuming your handler is placed next to `HttpRequestDecoder` public void channelRead(ChannelHandlerContext ctx, Object msg) {if (msg instanceof HttpRequest) {HttpRequest req = (HttpRequest) msg;...}if (msg instanceof HttpContent) {HttpContent content = (HttpContent) msg;try {...} finally {content.release();}} }

    如果你有疑慮,或者你想簡化釋放消息內存的過程,你可以使用ReferenceCountUtil.release():

    public void channelRead(ChannelHandlerContext ctx, Object msg) {try {...} finally {ReferenceCountUtil.release(msg);} }

    同樣地,你可以考慮繼承SimpleChannelHandler,它會幫你調用ReferenceCountUtil.release()釋放所有 你接收到的消息內存。

    • 出口消息

    與入口消息不同的是,出口消息是在你的應用中創建的,由Netty負責在將消息發送出去后釋放掉。但是,如果你 有攔截寫請求的handler程序,則需要保證正確釋放中間對象(例如,編碼程序)。

    public void write(ChannelHandlerContext ctx, Object message, ChannelPromise promise) {System.err.println("Writing: " + message);ctx.write(message, promise); } // Transformation public void write(ChannelHandlerContext ctx, Object message, ChannelPromise promise) {if (message instanceof HttpContent) {// Transform HttpContent to ByteBuf.HttpContent content = (HttpContent) message;try {ByteBuf transformed = ctx.alloc().buffer();....ctx.write(transformed, promise);} finally {content.release();}} else {// Pass non-HttpContent through.ctx.write(message, promise);} }

    三、內存泄漏

    引用計數的缺點是,引用計數對象容易發生泄露。因為JVM并不知道Netty的引用計數實現,當引用計數對象不可達時,JVM就會將它們GC掉,即時此時它們的引用計數并不為0。一旦對象被GC就不能再訪問,也就不能 歸還到緩沖池,所以會導致內存泄露。 慶幸的是,盡管發現內存泄露很難,但是Netty會對分配的緩沖區的1%進行采樣,來檢查你的應用中是否存在內存 泄露。

    文章轉自

    總結

    以上是生活随笔為你收集整理的Netty的引用计数对象的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 性爱视频免费 | 99久久婷婷国产综合精品草原 | 国产精品6666 | 中文字幕精品国产 | 日韩欧美中文在线 | 婷婷激情小说 | 操操久久 | 欧美大片黄 | 亚洲午夜精品一区二区三区他趣 | 第一页在线 | 成人手机在线播放 | av天堂一区二区三区 | 欧美福利视频 | 国产一二在线 | 日本亲与子乱ay中文 | www.com捏胸挤出奶 | 欧美精品一区三区 | japan粗暴video蹂躏 | 久久久婷| 青青草av在线播放 | 免费乱淫视频 | 少妇色综合 | 亚洲一区免费看 | 亚洲天堂av电影 | 成人高潮视频 | 中国字幕av | 91福利网| 精品人妻一区二区三区四区在线 | wwwxxx色 | 欧美裸体女人 | 日韩精品人妻无码一本 | 黑人巨大精品欧美一区二区蜜桃 | 久久久久久久一区二区三区 | 天天色天天干天天 | 淫人网 | 可以免费看的av | 亚洲狼人色 | 美女国产视频 | 久久久久国产精品一区二区 | 欧美女人天堂 | 麻豆免费在线观看 | 亚洲成人一区二区 | a级黄色小视频 | 国语精品 | 久久精品视频在线免费观看 | 亚洲欧美高清视频 | 日本人添下边视频免费 | 色猫咪av在线 | 久久久精品久久久久 | 午夜在线精品偷拍 | 欧美久久久影院 | 久久久久久久久久久久Av | 人人妻人人澡人人爽人人欧美一区 | 日本免费高清 | 玖玖玖精品 | www.久久国产 | 那个网站可以看毛片 | 2022精品国偷自产免费观看 | 中日韩在线播放 | 国产情侣av自拍 | 日本激情一区二区三区 | 在线免费视频一区 | www.色天使| 微拍福利一区二区 | 成人免费黄色 | 日韩大片免费在线观看 | 亚洲国产精品电影 | 日韩黄色短片 | 重口h文| 国产麻豆免费视频 | 国产午夜免费视频 | 日本一级淫片 | 一级爱爱片 | 在线视频97 | 欧美黄色a级片 | 丰满秘书被猛烈进入高清播放在 | ass大乳尤物肉体pics | 五月婷婷综合在线观看 | 天堂va在线| 婷婷av在线| 亚洲欧美精品aaaaaa片 | 狠狠干天天射 | 日韩精品麻豆 | 青青青草国产 | 五月婷婷导航 | 成人午夜精品一区二区三区 | 亚洲自拍第三页 | 国产aⅴ无码片毛片一级一区2 | 日本少妇xxxx | 久久久久久久久国产精品 | 国产三级在线观看完整版 | 亚洲视频999 | 麻豆传媒mv| 精品人妻无码专区视频 | 九一亚色 | 国内精品毛片 | 99久久久无码国产精品免费蜜柚 | youjizz自拍| 国产麻豆乱码精品一区二区三区 |