我正在运行一个使用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的专家。任何人都可以建议配置更改,这将导致我的磁盘层不使用堆外内存?或者,还有其他一些我完全误解其他人可以指出的东西吗?
谢谢!
答案 0 :(得分:1)
你如何衡量&#34;使用&#34;?
TL; DR否,磁盘层不会浪费RAM。
从{{3}开始,Ehcache使用内存映射文件进行磁盘持久性:
将Ehcache 2.x开源磁盘存储的端口替换为利用offheap库和内存映射文件的端口。
这意味着,Ehcache使用内存中的地址空间来访问磁盘上的文件。这确实占用了RAM的0个字节。 (至少是直接的。正如@ louis-jacomet已经说过的那样,操作系统可以决定将部分文件缓存在RAM中。)
当您在Linux上运行时,您应该比较流程的VIRT和RES值。 VIRT是进程使用的虚拟字节数。 RES是进程使用的实际RAM(RESident)字节数。 VIRT应该增加,同时填充磁盘存储缓存,但RES应保持相当稳定。