java中byte的用法_澄清池的工作原理

java中byte的用法_澄清池的工作原理缓冲区在计算机世界中随处可见,内存中的多级缓冲区,io设备的缓冲区等等,还有我们经常用的内存队列,分布式队列等等。缓冲区,平衡了数据产生方和数据消费方的处理效率差异,提高了数据处理性能。JDK为了解决网络通信中的数据缓冲问题,提供了ByteBuffer(heap或者直接内存缓存)来解决缓存问题,通过缓冲区来平衡网络io和CPU之间的速度差异,等待缓冲区积累到一定量的数据再统一交给CPU去处理,从而…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

缓冲区在计算机世界中随处可见,内存中的多级缓冲区,io设备的缓冲区等等,还有我们经常用的内存队列,分布式队列等等。缓冲区,平衡了数据产生方和数据消费方的处理效率差异,提高了数据处理性能。

JDK为了解决网络通信中的数据缓冲问题,提供了ByteBuffer(heap或者直接内存缓存)来解决缓存问题,通过缓冲区来平衡网络io和CPU之间的速度差异,等待缓冲区积累到一定量的数据再统一交给CPU去处理,从而提升了CPU的资源利用率。

Netty 使用 reference-counting(引用计数)来判断何时可以释放 ByteBuf 或 ByteBufHolder 和其他相关资源,从而可以利用池和其他技巧来提高性能和降低内存消耗。这一点上不需要开发人员做任何事情,但是在开发 Netty 应用程序时,尤其是使用 ByteBuf 和 ByteBufHolder时,你应该尽可能早地释放池资源。 Netty 缓冲 API 有以下几个优势:可以自定义缓冲类型

通过一个内置的复合缓冲类型实现零拷贝

扩展性好,比如 StringBuilder

不需要调用 flip() 来切换读/写模式

读取和写入索引分开

方法链

引用计数

Pooling(池)

ByteBuf 字节数据容器

写入数据到 ByteBuf 后,writerIndex(写入索引) 增加写入的字节数。读取字节后,readerIndex(读取索引) 也增加读取出的字节数。你可以读取字节,直到写入索引和读取索引处在相同的位置,此时ByteBuf不可读,所以下一次读操作将会抛出IndexOutOfBoundsException,就像读取数组时越位一样。

调用 ByteBuf 的以 “read” 或 “write” 开头的任何方法都将自动增加相应的索引(默认capaticy增加为原来的2倍)。另一方面,”set” 、 “get”操作字节将不会移动索引位置,它们只会在指定的相对位置上操作字节。可以给ByteBuf指定一个最大容量值,这个值限制着ByteBuf的容量。任何尝试将写入超过这个值的数据的行为都将导致抛出异常。ByteBuf 的默认最大容量限制是Integer.MAX_VALUE。

ByteBuf 类似于一个字节数组,最大的区别是读和写的索引可以用来控制对缓冲区数据的访问。下图显示了一个容量为16的空的 ByteBuf 的布局和状态,writerIndex 和 readerIndex 都在索引位置 0 :java中byte的用法_澄清池的工作原理

ByteBuf可以基于heap buffer,也可以基于direct buffer。使用direct buffer,通过免去中间交换的内存拷贝, 提升IO处理速度; 直接缓冲区的内容可以驻留在垃圾回收扫描的堆区以外。DirectBuffer 在-XX:MaxDirectMemorySize=xxM 大小限制下, 使用 Heap 之外的内存, GC对此”无能为力”,也就意味着规避了在高负载下频繁的GC过程对应用线程的中断影响。关于堆外内存详细讨论可参考:https://www.cnkirito.moe/nio-buffer-recycle。注意:使用完ByteBuf之后,一定要release,否则会造成内存泄漏。区分ByteBuf底层是heap buffer还是direct buffer,可以根据ByteBuf.hasArray()来判断,因为heap buffer返回true(heap上的ByteBuffy底层实现就是byte[] 数组),direct buffer返回false。

复合缓冲区 COMPOSITE BUFFER

复合缓冲区是多个ByteBuf组合的视图,复合缓冲区就像一个列表,我们可以动态的添加和删除其中的 ByteBuf,JDK的 ByteBuffer 没有这样的功能。Netty 提供了 ByteBuf 的子类 CompositeByteBuf 类来处理复合缓冲区。注意:CompositeByteBuf只是一个视图,CompositeByteBuf.hasArray() 总是返回 false,因为它可能既包含堆缓冲区,也包含直接缓冲区。

例如,一条消息由 header 和 body 两部分组成,将 header 和 body 组装成一条消息发送出去,可能 body 相同,只是 header 不同,使用CompositeByteBuf 就不用每次都重新分配一个新的缓冲区。下图显示CompositeByteBuf 组成 header 和 body:java中byte的用法_澄清池的工作原理

CompositeByteBuf使用示例:

ByteBuf byteBuf1 = UnpooledByteBufAllocator.DEFAULT.buffer();

ByteBuf byteBuf2 = UnpooledByteBufAllocator.DEFAULT.heapBuffer();

byteBuf1.writeByte(1);

byteBuf2.writeByte(2);

CompositeByteBuf compositeByteBuf = Unpooled.compositeBuffer();

compositeByteBuf.addComponent(byteBuf1);

compositeByteBuf.addComponent(byteBuf2);

System.out.println(compositeByteBuf.getByte(0));

System.out.println(compositeByteBuf.getByte(1));

ByteBuf allByteBuf = Unpooled.wrappedBuffer(byteBuf1, byteBuf2);

System.out.println(allByteBuf.getByte(0));

System.out.println(allByteBuf.getByte(1));

Netty Buffer

ByteBuf 是Netty中主要用来数据byte[]的封装类,主要分为Heap ByteBuf和Direct ByteBuf。为了减少内存的分配回收以及产生的内存碎片,Netty提供了PooledByteBufAllocator用来分配可回收的ByteBuf,可以把PooledByteBufAllocator看做一个池子,需要的时候从里面获取ByteBuf,用完了放回去,以此提高性能。当然与之对应的还有 UnpooledByteBufAllocator,顾名思义Unpooled就是不会放到池子里,所以根据该分配器分配的ByteBuf,不需要放回池子由JVM自己GC回收。

在netty中,根据ChannelHandlerContext 和 Channel获取的Allocator默认都是Pooled,所以需要在合适的时机对其进行释放,避免造成内存泄漏。Netty默认会在ChannelPipline的最后添加一个tail handler帮你完成ByteBuf的release。

在传递过程中自己通过Channel或ChannelHandlerContext创建的但是没有传递下去的ByteBuf也要手动释放。为了帮助你诊断潜在的泄漏问题,netty提供了ResourceLeakDetector,该类会采样应用程序中%1的buffer分配,并进行跟踪,不过不用担心这个开销很小。

// 第一种方式public void channelRead(ChannelHandlerContext ctx, Object msg) {

ByteBuf in = (ByteBuf) msg;

System.out.println(in.toString(CharsetUtil.UTF_8));

// 调用ctx.write(msg)不必手动释放了,Netty会自行作释放操作,但是如果调用 // ctx.write()两次或者调用ctx.write后又将该msg传递到了TailContext了,则就会报异常 ctx.write(msg);

}

// 第二种方式public void channelRead(ChannelHandlerContext ctx, Object msg) {

ByteBuf in = (ByteBuf) msg;

ByteBuf result = ctx.channel().alloc().buffer();

result.writeBytes(in.toString(CharsetUtil.UTF_8).getBytes(CharsetUtil.UTF_8));

ctx.write(result);

// msg对应的ByteBuf释放工作交给TailChannel来做 ctx.fireChannelRead(msg);

}

// 第三种方式public void channelRead(ChannelHandlerContext ctx, Object msg) {

ByteBuf in = (ByteBuf) msg;

ByteBuf result = ctx.channel().alloc().buffer();

result.writeBytes(in.toString(CharsetUtil.UTF_8).getBytes(CharsetUtil.UTF_8));

ctx.write(result);

// 手工释放ByteBuf in.release();

}

推荐阅读

欢迎小伙伴关注【TopCoder】阅读更多精彩好文。java中byte的用法_澄清池的工作原理

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/191859.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 程序员15k什么水平_初级码农

    程序员15k什么水平_初级码农前言大家好啊,我是秃顶的码哥!又是一年一度的高校毕业季,不少计算机专业的大学生已经踏上了求职之路,码哥我也想起了那天夕阳西下的奔跑,那是我逝去的青春啊!还记得我们那批同学毕业时,一起憧憬自己拿到15k、20K薪资的情景,但实际上,我们中绝大大部分的同学工作好几年了,还只是个拿几千工资的低级码农。现在码哥作为一枚已经秃顶的互联网行业老油条,下面就和大家分享一下如何避免成为低级码农的个人经验吧!以下几点如果你都能做到,月薪20k其实并不难哦!第一、多看计算机相关的书籍。读书一直是世界上性价比

    2022年9月30日
    2
  • 云服务器ECS和轻云服务器区别

    云服务器ECS和轻云服务器区别

    2021年5月25日
    158
  • NTP时间服务器简介

    NTP(NetworkTimeProtocol)网络时间协议,工作在UDP的123端口上。是用来使计算机时间同步化的一种协议,它可以使计算机对其服务器或时钟源(如石英钟,GPS等等)做同步化,它可以提供高精准度的时间校正(局域网上与标准间差小于1毫秒,互联网上几十毫秒),且可介由加密确认的方式来防止恶毒的协议攻击。NTP服务器NTP服务器提供准确时间,首先要有准确的时间来源,这一时间…

    2022年4月9日
    56
  • layer弹出层的关闭问题

    layer弹出层的关闭问题

    2021年10月17日
    38
  • PDAF原理简介_pfc电路工作原理图

    PDAF原理简介_pfc电路工作原理图PDAF原理原理及分类原理:是在感光芯片上预留出一些规律性对称的遮蔽像素点,专门用来进行相位检测,通过像素之间的距离及变化来决定对焦的偏移量即相位差(PD值)从而实现快速对焦。SP(shieledpixel)屏蔽掉像素一般的感光区域(黑色部分),值获得一半信号。需要另外的像素屏蔽掉另一半信号,得到完整的相位差信息。SP越多,对焦越快,但信号损失越严重,目前SP密度控制在1%~3%。屏蔽掉像素一般的感光区域(黑色部分),值获得一半信号。需要另外的像素屏蔽掉另一半信号,得到完整的相位差信息。S

    2025年9月29日
    2
  • oppo手机锁屏断网怎么解除_oppo手机锁屏的时间怎么调整位置

    oppo手机锁屏断网怎么解除_oppo手机锁屏的时间怎么调整位置oppo手机是有很多种锁屏时钟的,手机在息屏状态下,即可以查看时间,还可以在屏幕上显示很多相关的信息,不过很多小伙伴想要更多的个性化锁屏界面,比如把锁屏时钟调个位置和样式等等。那么oppo锁屏时钟怎么改格式?锁屏时钟位置在哪里设置调整呢?下面小编就来详细讲一讲!oppo锁屏时钟怎么改格式?锁屏时钟位置在哪里设置调整一、先来看oppo锁屏时钟怎么改格式?1、第一找到桌面上的“设置”—“显示与亮度”—…

    2022年9月29日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号