【问题标题】:Disk persistent cache in ehcache 3.4 is using (leaking?) direct memoryehcache 3.4 中的磁盘持久缓存正在使用(泄漏?)直接内存
【发布时间】:2018-04-14 08:50:47
【问题描述】:

我正在运行一个使用 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 的专家。任何人都可以建议进行配置更改以导致我的磁盘层不使用堆外内存吗?或者,我是否完全误解了其他人可以指出的其他内容?

谢谢!

【问题讨论】:

  • 一点进一步的信息:在测试时,我们大大减小了磁盘的大小(设置为 20mb),并且看到使用的堆外内存比这更多。我们希望在最坏的情况下,磁盘大小和堆外内存消耗之间存在 1 比 1 的相关性,但情况似乎并非如此。
  • 您能否具体说明您看到的增加的内存类型? Ehcache 3 磁盘使用java.nio.channels.FileChannel 来存储数据。虽然由于我们需要对数据结构的引用而看到堆的轻微增加是正常的,但 RAM 消耗不应该增加,除非您的操作系统进行缓存。

标签: ehcache ehcache-3


【解决方案1】:

你如何衡量“使用”?

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

截至v3.0.0 Ehcache 使用内存映射文件进行磁盘持久化:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-26
    • 2014-05-05
    • 1970-01-01
    • 1970-01-01
    • 2016-04-24
    • 1970-01-01
    • 2010-12-16
    • 2016-09-02
    相关资源
    最近更新 更多