为什么要写 direct-cache

上周测试了公司的项目之后,发现公司项目的接口执行时间波动很大。该项目里面,用到了 Ehcache 来缓存大量的大对象。所以,我开始怀疑是不是因为 Ehcache 引起频繁 GC 的原因。当时,想通过改用 Ehcache 官方的 BigMemory 再来测试一下。

后来发现 BigMemory 原来是不开源的,而且是一个收费软件。所以就自己动手写个了个简单的堆外缓存库direct-cache

但是,这只能说是个失败的库。

堆外内存

堆外内存,也叫 Off-head。我们平常说的 JVM 里面有两种内存,一种是堆,一种是栈。而堆外缓存,是一种 JVM 在直接在内存里面开启的一块内存区域。对象不能直接保存在这里面,只能通过序列化和反序列化来实现存取。

堆外内存有什么优缺点?

优点

堆外内存不影响 JVM GC,程序会减少 Full GC。

堆外内存速度比硬盘快。

IO 操作使用堆外内存比堆内存快。

缺点

堆外内存只能通过序列化和反序列化来存储,保存对象速度比堆内存慢。

direct-cache

direct-cache 的基础思路是程序一开始就初始化出几块内存区域(Allocator)。程序需要缓存对象的时候,路由到其中的一个 Allocator 中。

然后从该 Allocator 中的 Index 后面的开始保存该对象。如果已经到了 Allocator 的结尾,则重新从前面开始保存。同时删除前面所保存的对象。保存为之后,Index 需要重置到新保存对象的后面。

direct-cache堆外缓存设计思路

这样子做到先入先出,而且比较简单。

direct-cache 效果

direct-cache 确实实现了简单的堆外缓存效果。但是,也有很大的不足!

通过 JVM 监控软件看出程序跑的过程中,出现大量的 byte 数组和大量的 DirectByteBuffer 对象。这将会导致程序大量的 GC,失去了堆外缓存的意义。

direct-cache堆外缓存测试结果

direct-cache 还只能实现简单的先入先出缓存,没有其他缓存算法实现。

direct-cache 会先开启几块内存区域,在闲时,无法自动回收,减少内存使用量。

程序先放在这里,迟点再找时间改改。