JDK又在写Bug!告诉你为何Java NIO的ByteBuffer这么垃圾!(下)

简介: JDK又在写Bug!告诉你为何Java NIO的ByteBuffer这么垃圾!

readSlice、readRetainedSlice

image.png



返回部分空间,彼此共享底层缓冲区,会增加原缓冲区的readerIndex。


如果需要一个现有缓冲区的真实副本,请使用 copy()或者 copy(int, int),因为这个调用所返回的 ByteBuf 拥有独立的数据副本。



引用与释放

ByteBuf 在使用完毕后一定要记得释放,否则会造成内存泄露。


引用计数

通过在某个对象所持有的资源不再被其他对象引用时释放该对象所持有的资源来优化内存使用和性能的技术。

Netty 在4.x为 ByteBuf 和 ByteBufHolder 带来了引用计数技术,都实现了:



ReferenceCounted接口

需要显式释放的引用计数对象。

当一个新的ReferenceCounted被实例化时,以1 作为初始值。




retain()

增加引用计数,将引用计数加1。只要引用计数>0,就能保证对象不会被释放。

release()



减少引用计数,将引用计数减1。若引用计数减少到0 ,对象将被显式释放,并且访问释放的对象通常会导致访问冲突。


若实现ReferenceCounted的对象是其他实现ReferenceCounted的对象的容器,则当容器的引用计数变为 0 时,所包含的对象也将通过release()被释放。


引用计数对于池化实现(如 PooledByteBufAllocator)很重要,它降低了内存分配的开销。


Channel channel = ...;
// 从 Channel 获取 ByteBufAllocator
ByteBufAllocator allocator = channel.alloc();
...
// 从 ByteBufAllocator 分配一个 ByteBuf
ByteBuf buffer = allocator.directBuffer();
// 检查引用计数是否为预期的 1
assert buffer.refCnt() == 1;
ByteBuf buffer = ...;
// 减少该对象的活动引用。当减少到 0 时,该对象被释放,该方法返回 true
boolean released = buffer.release();

试图访问一个已经被释放的引用计数的对象,将会抛IllegalReferenceCountException

image.png



一个特定的(ReferenceCounted 的实现)类,可以用它自己的独特方式来定义它的引用计数规则。例如可以设想一个类,其 release()方法的实现总是将引用计数设为

零,而不用关心它的当前值,从而一次性使所有的活动引用都失效。



谁负责释放

一般由最后访问(引用计数)对象的那一方来负责将它释放。

目录
相关文章
|
4月前
|
Java 大数据
解析Java中的NIO与传统IO的区别与应用
解析Java中的NIO与传统IO的区别与应用
|
3月前
|
IDE Java 测试技术
如何优雅地根治Java中Null值引起的Bug问题
【8月更文挑战第18天】在Java开发中,null 值是一个既常见又危险的存在。它常常是导致程序崩溃、难以调试的“罪魁祸首”。然而,通过一系列优雅的策略和实践,我们可以有效地减少甚至根除由 null 值引发的Bug。本文将从多个方面探讨如何做到这一点。
82 4
|
3月前
|
存储 Java
如何在 Java 中写入和读取 ByteBuffer
【8月更文挑战第22天】
104 0
|
3月前
|
存储 Java
如何在 Java 中创建 ByteBuffer
【8月更文挑战第22天】
59 0
|
4月前
|
Java
Java中的NIO编程详解
Java中的NIO编程详解
|
4月前
|
Java 大数据
如何在Java中进行网络编程:Socket与NIO
如何在Java中进行网络编程:Socket与NIO
|
4月前
|
Java
Java中的NIO编程详解
Java中的NIO编程详解
|
5月前
|
存储 监控 Java
Java中的NIO编程实践精华
Java中的NIO编程实践精华
|
5月前
|
存储 SQL 关系型数据库
【BUG记录】Cause: java.sql.SQLException: Incorrect string value: '\xF0\x9F\x90\xA6' for column 'name' at row 1
在MySQL中遇到`Incorrect string value`错误通常是因为尝试插入的字符串包含不被数据库字符集支持的字符,如表情符号。错误根源是MySQL默认的utf8不支持4字节的UTF-8字符(如Emoji)。
402 1
|
5月前
|
Java 视频直播 数据库连接
Java I/O 模型详解:BIO、NIO 与 AIO 的特性与应用
Java I/O 模型详解:BIO、NIO 与 AIO 的特性与应用
65 2