今天简单的了解了一下HikariCP的原理,
记录了一下在HikariCP的github地址中学习到的东西。只是一个简单的了解,并没有深入的研究。
之所以去了解HikariCP是因为SpringBoot默认使用的是HikariCP数据库连接池,想简单的了解一下为什么SpringBoot会使用它,而不是其他的数据库连接池。
HikariCP数据源简述
HikariCP来自日文,是光的意思。听名字就可以知道它很快。
Fast, simple, reliable. HikariCP is a "zero-overhead" production ready JDBC connection pool. At roughly 130Kb, the library is very light.
快速,简单,可靠。HikariCP是一个零开销的数据库连接池。只有130KB的大小,十分的轻便
HikariCP和其他数据库连接池的比较
在HikariCP的github地址上,明晃晃的贴上了HikariCP和一些比较有名的数据库连接池的比较。可以看到HikariCP在一众数据库连接池中可谓是鹤立鸡群。
Tip: 我们常使用的SpringBoot框架内部默认的数据库连接池使用的就是HikariCP
HikariCP 为什么那么快?
1. hikariCP把ArrayList换成了FastList( FastList是HikariCP源码中自定义的一个类),该类消除了范围检查并执行了从尾到头的去除扫描.
原因:
因为ArrayList的get(index)每次调用的时候都会进行范围的检查,但是因为HikariCP可以提供范围得保证,因此范围检查显得就很多余。
ArrayList进行remove(Object)的时候是从头到尾扫描,但是实际上我们在关闭statement的时候,常常是逆向关闭,因此这种情况从尾部开始关闭更好。
public final class FastList extends ArrayList
2. ConcurrentBag
ConcurrentBag看名字就可以知道这个是和并发相关的,ConcurrentBag是HikariCP中的一个自定义的无锁集合,是从C#、.net中借鉴过来的。
主要的功能是:
A lock-free design
无锁的设计,锁会消耗系统资源,无锁在一定程度上节省了资源
ThreadLocal caching(ThreadLocal缓存)
Queue-stealing
// TODO 这个不知道啥意思哈,有待研究
Direct hand-off optimizations(直接交互的优化)
总而言之,concurrentBag通过一系列的操作,优化了并发
3. 使用invokestatic替换了invokevirtual
There are three things of note here:
The getstatic call is gone.
The invokevirtual call is replaced with a invokestatic call that is more easily optimized by the JVM.
Lastly, possibly not noticed at first glance is that the stack size is reduced from 5 elements to 4 elements. This is because in the case of invokevirtual there is an implicit passing of the instance of on the stack (i.e this), and there is an additional (unseen) pop of that value from the stack when getProxyPreparedStatement() was called.
大体意思是,在字节码层面上,
去掉了getstatic
使用invokestatic更容易被JVM优化
在stack(栈)里面对象由5个减少为了4个,因为使用invokevirtual会在stack中多生成一个代理工厂对象ProxyFactory
脑图: