你非要问我证据是什么,那么这两个单词呼应上了,你说这事多巧?
invokevirtual 调用的是虚方法,按照书里的说法,前面提到的 trap
其实就是这里的“逃生门”:
现在你知道为什么对于 JVM 来说, invokestatic 比 invokevirtual 更容易优化了吧?
优化指的就是内联。
invokestatic 调用的是静态方法,对于非虚方法,JVM 可以直接进行内联,这种内联是有百分之百的安全保障的。
而 invokevirtual 调用的是虚方法,对于虚方法的内联,就得上 CHA 机制,设置逃生门这一套玩意。
虽然都是内联,这不得多消耗一点性能嘛。
内联已经是性能优化了,让代码更好的内联,优化性能优化的优化。
这波操作,在大气层。
好了,上面就是字节码层面的优化了,接着我们看代码层面的优化。
代码层面的优化
代码层面上最出名的就是 FastList 替换 ArrayList 这个玩意了。
备注的后半部分我们应该很熟悉了,前面已经讲过了。
前面就是用 FastList 替换 ArrayList 的那一次提交。
Java ArrayList 在每次调用 get(int index) 时都会进行范围检查。在 HikariCP 项目中,可以保证 index 在正确的范围内,所以这个检查没有意义,于是就去掉了:
再比如,ArrayList 的 remove(Object o) 方法是从头扫到尾。
假设要删除最后一个元素,需要遍历整个数组。
巧就巧在,比如 HikariCP 的 Statement,按照我们的编码习惯,删除(关闭)应该先删除最后一个。
所以 FastList 优化了 remove(Object element) 方法, 将查找顺序变成了逆序查找:
整体来看,FastList 的优化点就上面说的 get 和 remove 方法。
接着,看看另外一个代码级别的优化:
作者列了几个点:
- 一个无锁的设计
- 线程本地缓存
- 窃取队列
- 直接交接的优化
作者介绍的很简单,其实这里面还是很有东西的。
一个重要的技巧是 ConcurrentBag 通过 ThreadLocal 做了一次连接的预分配。
通过 ThreadLocal 一定程度上避免了共享资源的竞争。
自己看代码的话主要看看 add(空闲连接加入队列)、borrow(获取连接)、requite(释放连接) 方法。
网上也有很多相应的文章去介绍,有兴趣的可以去了解一下,我这就不写了。
哦,你不想看其他的文章,就想等着我给你讲呢? 好的,先欠着,欠着。 偷个懒,文章写太长了也没人看。
打起来了
在写文章的过程中,我还看到了这样的一个 issue,感觉有点意思,写一下。
一个小哥说:
你好,我觉得你对 Java 数据库池的分析很有参考价值。我碰巧遇到了阿里巴巴的这个 druid 线程池(号称是Java中最快的数据库池!)。从我的快速浏览来看,它似乎有一些很酷的功能。对此有什么想法吗。谢谢。
HikariCP 的作者很快就进行了回复:
至少在他的基准测试中,Druid 在获取和返回连接方面是最慢的,而在创建和关闭语句方面是第三快的。他们维基中的基准页面没有显示他们是用什么配置运行的,但我怀疑他们禁用了借来的测试。虽然我不会说这是 "作弊",但这不是我在生产上的使用方式。据我所知,他们也没有提供他们测试源代码。
这就有点意思了。
虽然我不会说这是"作弊",这话说的,就像是:有一句话我不知当讲不当讲。
然后就接着讲出来了。
接着,另外一个吃瓜网友说:
Druid 的设计理论是专注于监控和数据访问行为的增强(如自动数据库切片)。它提供了一个SQL解析器来分析用户的SQL查询,并收集了很多数据用来监控。因此,如果你需要一个 JDBC 监控解决方案,你可以试试 Druid。
HikariCP 的作者也表示这句话没毛病,但是他强调了自己的 HikariCP 也是给监控留了口子的:
这是一个有效的观点。我想指出,HikariCP也提供监控数据,但提供的指标是 "池级 "指标,并不具体到查询执行时间等。
上面的对话,都是发生在 2015 年 1 月。
但是一年半后, 2016 年 7 月 26 日,这个问题又被一个人激活了:
此人正是 druid 的爸爸之一,江湖人称温少。
也许你不认识温少,也许你不知道温少写的 druid,但是你一定知道温少的另外一个大作:
问题是多了一点,但是并不妨碍别人是大神。
可以直接端茶:
首先温少说:如果你配置了maxWait 属性,druid 会使用公平锁,所以降低了性能。
至于为什么这样的,是因为在生产环境中遇到的一些问题,设计如此。
然后他接着提到了淘宝:
说的是 2015 年的天猫双 11。
标题翻译过来就是:
阿里巴巴集团在光棍节销售的前90分钟内销售了50亿美元。
我还在链接里面看到了好久没见的马爸爸:
我理解温少放这个链接的意思就是说,druid 在阿里内部使用,天猫双十一是一个非常牛逼的场景,druid 经受住了这样场景的考验。
HikariCP 的作者并没有回复温少。
直到另外一个吃瓜群众的推波助澜:
HikariCP 是世界上使用最广泛的连接池之一,被一些最大的公司使用,每天为数十亿的用户提供服务。
而对于 Druid,不好意思,我说话有点直:在中国以外的地方很少见。
但是对于他的这个回答,很快就有人提出了质疑:
一些最大的公司都在使用,每天为数十亿用户服务?比如说呢?
要数据是吧?坐稳了:
- wix.com托管着超过1.09亿个网站,每天处理的请求超过10亿个。
- Atlassian的产品拥有数百万的客户。
- HikariCP是 spring boot 的默认连接池。
- HikariCP每月从中央maven仓库解析超过30万次。
这些公司都在用:
这个回答之后,双方都没有说话了。
两方之间的 battle 就算是结束了。
但是还有人在继续跟帖,我觉得这个哥们属于清醒吃瓜:
别吵了,别吵了。我特么来这里是学技术的,不是来看你们讨论 "资本主义"工具和 "共产主义"工具的区别的。
而我觉得,这场 battle 其实真的没有特别大的意义。
在技术选型上,没有最好的,只有合适的。
Druid 和 HikariCP 各有各的优势。
最后说一句(求关注)
好了,看到了这里点个关注吧,周更很累的,需要一点正反馈。
感谢您的阅读,我坚持原创,十分欢迎并感谢您的关注。