ehcache 3.4中的磁盘持久缓存正在使用(泄漏?)直接内存



我正在运行一个使用Ehcache 3.4.0的web应用程序。我有一个缓存配置,它定义了1000个内存对象的简单默认值:

<cache-template name="default">
<key-type>java.lang.Object</key-type>
<value-type>java.lang.Object</value-type>
<heap unit="entries">1000</heap>
</cache-template>

然后,我有一些基于磁盘的缓存,它们使用这个默认模板,但覆盖所有值(以编程方式生成,所以这就是为什么它们甚至使用默认模板的原因),如下所示:

<cache alias='runViewCache' uses-template='default'>
<key-type>java.lang.String</key-type>
<value-type>java.lang.String</value-type>
<resources>
<heap unit='entries'>1</heap>
<disk unit='GB' persistent='true'>1</disk>
</resources>
</cache>

当数据写入基于磁盘的缓存时,JVM会使用直接/堆外内存,并且永远不会释放。即使清除缓存也不会释放内存。所使用的内存与写入基于磁盘的缓存的数据直接相关(据我所知,几乎是逐字节的)。

此缓存的权威层是org.ehcache.impl.internal.store.disk.OffHeapDiskStore.的实例

这似乎是内存泄漏(内存被消耗,从未释放),但我绝不是配置ehcache的专家。有人能建议更改配置,使我的磁盘层不使用堆外内存吗?或者,还有什么我完全误解了的东西,别人可以指出吗?

谢谢!

如何衡量"已使用"?

TL;DR否,磁盘层不会浪费RAM。

从v3.0.0开始,Ehcache使用内存映射文件实现磁盘持久性:

将Ehcache2.x开源磁盘存储的端口替换为利用堆外库和内存映射文件的端口。

这意味着,Ehcache使用内存中的地址空间来访问磁盘上的文件。这确实会消耗0字节的RAM。(至少直接。正如@louis jacomet已经说过的,操作系统可以决定将部分文件缓存在RAM中。)

当您在Linux上运行时,您应该比较进程的VIRT和RES值。VIRT是进程使用的虚拟字节数。RES是进程使用的实际RAM(RESident)字节数。当磁盘存储缓存被填充时,VIRT应该会增加,但RES应该保持相当稳定。

最新更新