Update Recycler对象池原理分析.md

pull/62/head
Yang Libin 4 years ago committed by GitHub
parent f35b4753e5
commit 9d42c66002
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -8,7 +8,7 @@ Recycler 是 Netty 中基于 ThreadLocal 的轻量化的对象池实现。既然
Recycler 对象池在 netty 中最重要的使用,就在于 netty 的池化 ByteBuf 的场景下。首先,何为池化?以 PooledDirectByteBuf 举例,每一个 PooledDirectByteBuf 在应用线程中使用完毕之后,并不会被释放,而是等待被重新利用,类比线程池每个线程在执行完毕之后不会被立即释放,而是等待下一次执行的时候被重新利用。所谓的对象池也是如此,池化减少了 ByteBuf 创建和销毁的开销,也是 netty 高性能表现的基石之一。
```
```java
private static final Recycler<PooledDirectByteBuf> RECYCLER = new Recycler<PooledDirectByteBuf>() {
@Override
protected PooledDirectByteBuf newObject(Handle<PooledDirectByteBuf> handle) {
@ -32,7 +32,7 @@ Recycler 中,最核心的是两个通过 ThreadLocal 作为本地线程私有
- 第一个成员是在 Recycler 被定义的 Stack 成员对象。
```
```java
private final FastThreadLocal<Stack<T>> threadLocal = new FastThreadLocal<Stack<T>>() {
@Override
protected Stack<T> initialValue() {
@ -44,7 +44,7 @@ Recycler 中,最核心的是两个通过 ThreadLocal 作为本地线程私有
顾名思义,这个 Stack 主体是一个堆栈,但是其还维护着一个链表,而链表中的每一个节点都是一个队列。
```
```java
private DefaultHandle<?>[] elements;
private WeakOrderQueue cursor, prev;
```
@ -53,7 +53,7 @@ Recycler 中,最核心的是两个通过 ThreadLocal 作为本地线程私有
- 第二个成员是在 Recycler 中也是通过 ThreadLocal 所实现的一个线程本地变量DELAYED_RECYCLED ,是一个 Stack 和队列的映射 Map。
```
```java
private static final FastThreadLocal<Map<Stack<?>, WeakOrderQueue>> DELAYED_RECYCLED =
new FastThreadLocal<Map<Stack<?>, WeakOrderQueue>>() {
@Override
@ -67,7 +67,7 @@ Recycler 中,最核心的是两个通过 ThreadLocal 作为本地线程私有
在前一个成员的解释中提到,当别的线程调用另一个线程的对象池的 recycle()方法进行回收的时候,并不会直接落到持有对象池的线程的 Stack 数组当中当然原因也很简单在并发情况下这样的操作显然是线程不安全的而加锁也会带来性能的开销。因此netty 在 Recycler 对象池中通过更巧妙的方式解决这一问题。
在前面提到除了数组Stack 还持有了一系列队列的组成的链表,这些链表中的每一个节点都是一个队列,这些队列又存放着别的线程所回收到当前线程对象池的对象。那么,这些队列就是各个线程针对持有对象池的专属回收队列,说起来很拗口,看下面的代码。
```
```java
private void pushLater(DefaultHandle<?> item, Thread thread) {
// we don't want to have a ref to the queue as the value in our weak map
// so we null it out; to ensure there are no races with restoring it later
@ -111,7 +111,7 @@ private WeakOrderQueue(Stack<?> stack, Thread thread) {
pushLater()方法发生在当一个对象被回收的时候,当当前线程不是这个对象所申请的时候的线程时,将会通过该对象的 Stack 直接去通过 DELAYED_RECYCLED 映射到一条队列上,如果没有则创建并建立映射,再把该对象放入到该队列中,以上操作结束后该次回收即宣告结束
```
```java
private WeakOrderQueue(Stack<?> stack, Thread thread) {
head = tail = new Link();
owner = new WeakReference<Thread>(thread);

Loading…
Cancel
Save