我们接着之前的代码
看Sender.java中的completeBatch方法
//TODO 核心代码 把异常信息也带过去了
//回调函数调用完之后
//说明一个完整的消息发送流程就结束了
batch.done(baseOffset, timestamp, exception);
this.accumulator.deallocate(batch);
这次我们看accumulator,因为done之后消息发送流程就完成了,看接下来做了什么操作
这里看它调用的方法deallocate,这个应该就是回收了资源
public void deallocate(RecordBatch batch) {
//从incomplete里面移除已经成功处理的批次
incomplete.remove(batch);
//释放内存
free.deallocate(batch.records.buffer(), batch.records.initialCapacity());
}
我们主要看如何释放内存
public void deallocate(ByteBuffer buffer, int size) {
lock.lock();
try {
//如果还回来的内存的大小等于一个批次的大小
if (size == this.poolableSize && size == buffer.capacity()) {
//内存里面的东西清空
buffer.clear();
//把内存放入到内存池
this.free.add(buffer);
} else {
//如果释放的内存大小不是一个批次大小
//那就归为可用内存availableMemory 等着垃圾回收即可
this.availableMemory += size;
}
Condition moreMem = this.waiters.peekFirst();
if (moreMem != null)
//释放了内存(还了内存以后)
//都会唤醒等待内存的线程
//接下来还是要唤醒真正等待分配内存的线程
moreMem.signal();
} finally {
lock.unlock();
}
}
看到这个就很熟悉,之前在内存池那分析过,这里要么将内存还给内存池,要么归为可用内存等待gc,再唤醒等待内存的线程,循环工作