深入拆解 Tomcat & Jetty
李号双
eBay 技术主管
38890 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 45 讲
开篇词 (1讲)
深入拆解 Tomcat & Jetty
15
15
1.0x
00:00/00:00
登录|注册

20 | 总结:Tomcat和Jetty中的对象池技术

场景中可以用池化技术优化的情况
适用场景
对象池技术的作用
对象池使用小贴士
内存泄露问题
对象池大小的限制
无锁化设计
多线程竞争和锁竞争
桶管理不同长度的ByteBuffer
ArrayByteBufferPool实现类
ByteBufferPool接口
为什么选择SynchronizedStack
使用数组实现栈的功能
SynchronizedStack类实现
高成本的对象初始化
大型复杂Java对象
Java对象数量多且存在时间短
以空间换时间的思路
对象池技术的作用
Java对象的创建、初始化和GC的资源消耗
课后思考
本期精华
对象池的思考
Jetty的ByteBufferPool
Tomcat的SynchronizedStack
适用场景
对象池技术概述
Tomcat和Jetty中的对象池技术
对象池技术

该思维导图由 AI 生成,仅供参考

Java 对象,特别是一个比较大、比较复杂的 Java 对象,它们的创建、初始化和 GC 都需要耗费 CPU 和内存资源,为了减少这些开销,Tomcat 和 Jetty 都使用了对象池技术。所谓的对象池技术,就是说一个 Java 对象用完之后把它保存起来,之后再拿出来重复使用,省去了对象创建、初始化和 GC 的过程。对象池技术是典型的以空间换时间的思路。
由于维护对象池本身也需要资源的开销,不是所有场景都适合用对象池。如果你的 Java 对象数量很多并且存在的时间比较短,对象本身又比较大比较复杂,对象初始化的成本比较高,这样的场景就适合用对象池技术。比如 Tomcat 和 Jetty 处理 HTTP 请求的场景就符合这个特征,请求的数量很多,为了处理单个请求需要创建不少的复杂对象(比如 Tomcat 连接器中 SocketWrapper 和 SocketProcessor),而且一般来说请求处理的时间比较短,一旦请求处理完毕,这些对象就需要被销毁,因此这个场景适合对象池技术。

Tomcat 的 SynchronizedStack

Tomcat 用 SynchronizedStack 类来实现对象池,下面我贴出它的关键代码来帮助你理解。
public class SynchronizedStack<T> {
//内部维护一个对象数组,用数组实现栈的功能
private Object[] stack;
//这个方法用来归还对象,用synchronized进行线程同步
public synchronized boolean push(T obj) {
index++;
if (index == size) {
if (limit == -1 || size < limit) {
expand();//对象不够用了,扩展对象数组
} else {
index--;
return false;
}
}
stack[index] = obj;
return true;
}
//这个方法用来获取对象
public synchronized T pop() {
if (index == -1) {
return null;
}
T result = (T) stack[index];
stack[index--] = null;
return result;
}
//扩展对象数组长度,以2倍大小扩展
private void expand() {
int newSize = size * 2;
if (limit != -1 && newSize > limit) {
newSize = limit;
}
//扩展策略是创建一个数组长度为原来两倍的新数组
Object[] newStack = new Object[newSize];
//将老数组对象引用复制到新数组
System.arraycopy(stack, 0, newStack, 0, size);
//将stack指向新数组,老数组可以被GC掉了
stack = newStack;
size = newSize;
}
}
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Tomcat和Jetty中的对象池技术是为了减少频繁创建和销毁Java对象所带来的资源开销。文章介绍了Tomcat中的SynchronizedStack和Jetty中的ByteBufferPool两种对象池实现方式。SynchronizedStack使用数组来维护对象,减少内存开销,而ByteBufferPool则通过桶管理不同长度的ByteBuffer对象,避免频繁的内存分配和释放。对象池技术适用于处理短时间内需要大量复杂对象的场景,如HTTP请求处理。然而,对象池也面临着线程同步开销和内存泄漏的问题,需要注意对象的归还、重置和资源限制。总之,对象池技术在减少资源开销、提高性能方面具有重要意义,特别适用于需要限制资源使用的场景,如数据库连接池。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《深入拆解 Tomcat & Jetty 》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(22)

  • 最新
  • 精选
  • 802.11
    工厂模式和池化思想有什么区别呢

    作者回复: 工厂模式没有一个池来存对象,并且侧重不同,工厂模式是设计上的考虑,不是性能方面的

    2019-06-27
    2
    15
  • yang
    同步栈有看到,但是不知道它是做池化用的 😂😂😂 线程池 里面维护了线程数组和任务队列 连接池 jvm的常量池 ?

    作者回复: 常量池也是一种池化

    2019-08-15
    5
  • -W.LI-
    老师好学到了。通过threadlocal来减少锁竞争上下文切换的开销。 可是我看见好多帖子说threadlocal容易内存泄露啥的肯比较多需要慎用。五年码龄从没用过😂。 请教一个问题threadLocal中的对象如果用完不清。下次别的请求Tomcat线程池中拿到同个线程,能取到之前请求存入的数据么?

    作者回复: 会的,所以要及时清理

    2019-06-25
    4
    5
  • 清风
    也看了些书上的讲解,看完后还是没有像老师这样能总结出一个清晰的逻辑结构,这样的情况需要怎么办呢

    作者回复: 可以从why what how 整理一下思路

    2019-07-01
    3
    4
  • Liam
    tomcat和jetty的对象池没有空闲超时/超量回收的机制吗?

    作者回复: 似乎没有,对象池大小靠连接数限制

    2019-06-25
    4
  • kyon
    您好,请问 ArrayByteBufferPool 中,direct 和 indirect 都是 new 出来的,区别是什么?另外在 new ByteBufferPool.Bucket(this,size,_maxQueue) 中,参数 _maxQueue 的作用是什么?

    作者回复: APR那篇有详细解释,HeapByteBuffer与DirectByteBuffer的区别。 maxqueue 的作用是控制内存池的总大小

    2019-06-26
    3
  • WL
    请问老师Tomcat为什么用栈做对象池,那要去栈底的对象不是很麻烦很不灵活吗?为啥不用map的方式呢?

    作者回复: 不会要去栈底找对象的情况,对象都是无差别的

    2019-06-25
    3
    2
  • XxxxxxxMr
    老师 我有一个疑问 池化。对象池 、线程池 、数据库连接池等等 他们都是如出一辙吗?还是大同小异

    作者回复: 基本思想都一样

    2019-09-16
  • TJ
    为什么tomcat不使用java本身的stack class? 它也是基于数组的。自己再加一个同步就可以了

    作者回复: java本身的stack是不是实现上有点复杂,这里要尽量简单

    2019-06-25
  • 肖臧
    Java的Integer类的IntegerCache就是利用了池化技术,还有String.intern()也算池化技术
    2020-06-05
    6
收起评论
显示
设置
留言
22
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部