首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

Netty精粹之轻量级内存池技术实现原理与应用(2)

Netty精粹之轻量级内存池技术实现原理与应用(2)

Recycler实现原理
我先给出一张总的示意图,下面如果有看不懂的地方可以结合这张图来理解:

上图代表着Recycler的工作示意图。Recycler#get是向外部提供的从对象池获取对象的接口:
1
2
3
4
5
6
7
8
9
<code class="hljs kotlin"><span class="hljs-keyword">public <span class="hljs-keyword">final T <span class="hljs-keyword">get() {
    Stack<T> stack = threadLocal.<span class="hljs-keyword">get();
    DefaultHandle handle = stack.pop();
    <span class="hljs-keyword">if (handle == <span class="hljs-literal">null) {
        handle = stack.newHandle();
        handle.value = newObject(handle);
    }
    <span class="hljs-keyword">return (T) handle.value;
}</span></span></span></span></span></span></span></code>



Recycler首先从当前线程绑定的值中获取stack,我们可以得知Netty中其实是每个线程关联着一个对象池,直接关联对象为Stack,先看看池中是否有可用对象,如果有则直接返回,如果没有则新创建一个Handle,并且调用newObject来新创建一个对象并且放入Handler的value中,newObject由用户自己实现。
当Recycler使用Stack的pop接口的时候,我们看看:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<code class="hljs gradle">DefaultHandle <span class="hljs-keyword">pop() {
    <span class="hljs-keyword">int <span class="hljs-keyword">size = <span class="hljs-keyword">this.<span class="hljs-keyword">size;
    <span class="hljs-keyword">if (<span class="hljs-keyword">size == <span class="hljs-number">0) {
        <span class="hljs-keyword">if (!scavenge()) {
            <span class="hljs-keyword">return <span class="hljs-keyword">null;
        }
        <span class="hljs-keyword">size = <span class="hljs-keyword">this.<span class="hljs-keyword">size;
    }
    <span class="hljs-keyword">size --;
    DefaultHandle ret = elements[<span class="hljs-keyword">size];
    <span class="hljs-keyword">if (ret.lastRecycledId != ret.recycleId) {
        <span class="hljs-keyword">throw <span class="hljs-keyword">new IllegalStateException(<span class="hljs-string">"recycled multiple times");
    }
    ret.recycleId = <span class="hljs-number">0;
    ret.lastRecycledId = <span class="hljs-number">0;
    <span class="hljs-keyword">this.<span class="hljs-keyword">size = <span class="hljs-keyword">size;
    <span class="hljs-keyword">return ret;
}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>



首先看看Stack的elements数组是否有对象可用,如果有则将size大小减1,返回对象。如果elements数组中已经没有对象可用,则需要从仓库中查找是够有可以用的对象,也就是scavenge的实现,scavenge具体调用的是scavengeSome。Stack的仓库是由WeakOrderQueue连接起来的链表实现的,Stack维护着链表的头部指针。而每个WeakOrderQueue又维护着一个链表,节点由Link实现,Link的实现很简单,主要是继承AtomicInteger类另外还有一个Handle数组、一个读指针和一个指向下一个节点的指针,Link巧妙的利用AtomicInteger值来充当数组的写指针从而避免并发问题。
返回列表