Netty之了解 Recycler 对象回收池

简介: Netty之了解 Recycler 对象回收池

前言

RecyclerNetty中的对象回收池, 用于复用对象, 减少内存分配和GC操作的次数, 它通过双向链表维护对象池, 在对象被回收的时候将其插入到链表的头部, 在对象需要被分配时从链表的头部取出, 这样可以减少内存分配的次数, 提高系统的效率, 接下来让我们学习一下Recycler 的复用对象


自定义 User 类的对象复用

首先我们创建一个User类, 定义一个属性Recycler.Handle<User> handle, 并重写销毁方法recycler()和构造方法

publicclassUser {
privateStringname;
privateRecycler.Handlehandle;
publicvoidsetName(Stringname) {
this.name=name;
    }
publicStringgetName() {
returnname;
    }
publicUser(Recycler.Handlehandle) {
this.handle=handle;
    }
publicvoidrecycle() {
handle.recycle(this);
    }
@OverridepublicStringtoString() {
return"User{"+"name='"+name+'\''+", handle="+handle+'}';
    }
}


然后去创建`User`类的对象回收池`UserRecycler`类, 让这个类去继承`Recycler`对象回收类, 并重写抽象方法`newObject(Handle handle)`

publicclassUserRecyclerextendsRecycler{
@OverrideprotectedUsernewObject(Handlehandle) {
returnnewUser(handle);
    }
}

最后我们创建一个`Test`测试类, 写一个`mian`方法来对我们自定义的对象回收池来进行测试

publicclassTest {
publicstaticvoidmain(String[] args) {
// 创建对象回收池对象RecycleruserRecycler=newUserRecycler();
// 从对象回收池中获取对象Useruser1=userRecycler.get();
// 赋予对象属性值user1.setName("宁轩");
// 回收 user1user1.recycle();
// 重新从对象回收池中获取对象Useruser3=userRecycler.get();
// 判断两个对象是否相等System.out.println(user1==user3);
// 输出新获取对象的 name 属性System.out.println(user3);
    }
}

我们测试的流程大概如下:

  • 先通过对象池获取 对象A
  • 给 对象A 赋予值
  • 销毁 对象A
  • 再次从对象池中获取 对象B
  • 判断 对象A 是否等于 对象B
  • 输出 对象B 的 name 属性

下图是我们的测试结果, 可以看到, 我们新创建的对象user3 和之前创建的对象user1 是完全相等的

面试小知识: == 判断的是引用地址, equals 判断的是值, 需要重写 equals()方法

image.png

那么有没有可能每一次创建的对象都是一个? 接下来我们继续测试

本次测试, 其他不变, 继续从对象池中获取新的对象 user4, 然后和 user1 进行判断, 可以看到, 他俩完全不一样, user4 是一个纯纯的`新对象`

image.png

本次测试, 将 user1 销毁的步骤注释掉, 可以看到, 这个时候 `user1 != user3`, 这两个对象也不一样了

image.png

由此可得知, 当一个对象销毁之后, 再次从对象池中获取到的就是该对象, 若对象池中没有已销毁的对象, 那么获取到的就是新对象, 此时我们在回顾一下`前言`的内容, 是不是更加理解了呢

image.png

总结

本篇文章就到这里了, 通过本篇文章的学习, 我们能够理解了NettyRecycler究竟是什么, 有什么作用, 但是他的内部结构和各种方法我们都没有去详细的研究, 这就交给下一篇文章了, 最后我们一起简单的实现了一下对象池希望对大家理解Recycler有所帮助

目录
相关文章
|
Java
05RPC - netty发送对象
05RPC - netty发送对象
39 0
|
7月前
|
编解码 前端开发 网络协议
Netty Review - ObjectEncoder对象和ObjectDecoder对象解码器的使用与源码解读
Netty Review - ObjectEncoder对象和ObjectDecoder对象解码器的使用与源码解读
171 0
|
缓存 前端开发 Java
【Netty官方文档翻译】引用计数对象(reference counted objects)
【Netty官方文档翻译】引用计数对象(reference counted objects)
94 0
|
Java 应用服务中间件 程序员
netty系列之:使用Jboss Marshalling来序列化java对象
在JAVA程序中经常会用到序列化的场景,除了JDK自身提供的Serializable之外,还有一些第三方的产品可以实现对JAVA对象的序列化。其中比较有名的就是Google protobuf。当然,也有其他的比较出名的序列化工具,比如Kryo和JBoss Marshalling。
|
XML 编解码 JSON
netty案例,netty4.1中级拓展篇三《Netty传输Java对象》
Netty在实际应用级开发中,有时候某些特定场景下会需要使用Java对象类型进行传输,但是如果使用Java本身序列化进行传输,那么对性能的损耗比较大。为此我们需要借助protostuff-core的工具包将对象以二进制形式传输并做编码解码处理。与直接使用protobuf二进制传输方式不同,这里不需要定义proto文件,而是需要实现对象类型编码解码器,用以传输自定义Java对象。
269 0
netty案例,netty4.1中级拓展篇三《Netty传输Java对象》
|
安全 Java
窥探 Netty 源码!Recycler 对象池实现原理剖析
该文所涉及的 netty 源码版本为 4.1.6。
275 0
|
存储 算法 Java
netty系列之:netty中常用的对象编码解码器
我们在程序中除了使用常用的字符串进行数据传递之外,使用最多的还是JAVA对象。在JDK中,对象如果需要在网络中传输,必须实现Serializable接口,表示这个对象是可以被序列化的。这样就可以调用JDK自身的对象对象方法,进行对象的读写。 那么在netty中进行对象的传递可不可以直接使用JDK的对象序列化方法呢?如果不能的话,又应该怎么处理呢? 今天带大家来看看netty中提供的对象编码器。
|
网络协议 Java 前端开发
netty tcp 字节有序-&gt;对象有序
io.netty.handler.codec.serialization.ObjectDecoder 将ByteBuf[]反序列化为java对象。 A decoder which deserializes the received ByteBufs into Java objects.  io.netty.handler.codec.serialization.ObjectEncod
1468 0
|
存储 缓存 NoSQL
跟着源码学IM(十一):一套基于Netty的分布式高可用IM详细设计与实现(有源码)
本文将要分享的是如何从零实现一套基于Netty框架的分布式高可用IM系统,它将支持长连接网关管理、单聊、群聊、聊天记录查询、离线消息存储、消息推送、心跳、分布式唯一ID、红包、消息同步等功能,并且还支持集群部署。
13531 1
|
7月前
|
消息中间件 Oracle Dubbo
Netty 源码共读(一)如何阅读JDK下sun包的源码
Netty 源码共读(一)如何阅读JDK下sun包的源码
145 1