代码之家  ›  专栏  ›  技术社区  ›  StaxMan

是否有任何Java缓存可以限制内存中缓存的内存使用,而不仅仅是实例数?

  •  12
  • StaxMan  · 技术社区  · 17 年前

    EhCache可能会工作,但它似乎没有提供我需要的一件事:不限制缓存对象的数量,而是(近似)限制缓存数据消耗的内存量。

    我知道,如果不进行序列化,很难计算出给定对象的确切内存使用情况(一般情况下,我希望避免这种情况,因为它的速度太慢,无法满足我的使用目的),我自己也可以提供大小估计。

    那么:是否有一个简单的开源java缓存允许定义缓存对象的“权重”,以限制缓存的内容量?

    Java CacheMate 它试图解决这个问题,同时还有一些其他改进想法(多级内存进程内缓存)

    8 回复  |  直到 15 年前
        1
  •  3
  •   Ben Manes    17 年前

    我同意Paul的观点,这通常通过使用软引用缓存来解决,尽管它可能会比您希望的更早地逐出条目。一个通常可以接受的解决方案是使用一个正常的缓存,将其逐出到软缓存,并在可能的情况下恢复未命中的条目。这种受害者缓存方法工作得很好,给了你一个较低的标准,但如果可用内存的话,会有额外的好处。

    http://sourceforge.net/projects/sizeof ).我只是出于调试目的才使用它,我建议在将其用于正常使用之前对开销进行基准测试。

    在我的缓存库中,我计划在核心算法实现后添加插入计算器的功能。通过这种方式,可以将集合存储为值,但通过所有集合大小的总和绑定缓存。我见过无限的集合,因为缓存中的值会导致OutOfMemoryException,所以控制非常方便。

    如果您真的需要此功能,我建议您不要这样做,我们可以增强当前的实现以支持此功能。你可以给我发电子邮件,ben.manes-at-gmail.com。

        2
  •  2
  •   ReneS    17 年前

    这会将缓存限制在可用内存量内,但不会杀死程序的其余部分,因为Java会在内存需要时删除软引用。。。不全是。。最老的第一个。。。通常如果将引用队列添加到实现中,还可以从映射中删除暂停条目(仅键,无值)。

        3
  •  2
  •   Snehal    14 年前

    EhCache V2.5目前提供了一种解决方案,可以根据缓存的内存大小设置上限。有关更多详细信息,请查看 EhCache 2.5 Documentation

        4
  •  1
  •   Jon Skeet    17 年前

    这不仅很难衡量,也很难定义。

    二者都 计算该字符串的大小,尽管从缓存中删除其中任何一个都不会使该字符串符合垃圾收集的条件?尽管事实上如果 如果从缓存中删除了其中的一个字符串,那么该字符串是否符合收集条件?如果缓存中没有的另一个对象引用了该字符串,该怎么办?

    如果你能准确描述你感兴趣的尺寸 可以通过编程来确定它——但我怀疑你会发现甚至很难决定你到底想要什么。

        5
  •  0
  •   Tom Hawtin - tackline    17 年前

    除了猜测对象的内存使用情况外,对于一个合理的算法,您还需要猜测重新创建它的成本。一个合理的猜测是,娱乐的成本大致与内存大小成正比。因此,这些因素相互抵消,两者都不需要。一个简单的算法可能会更好。

        6
  •  0
  •   Alexander Torstling    17 年前

    如果无法进行任何估计,请编写缓存逐出策略,该策略基于JVM堆大小(从系统轮询)或由来自孤立对象(在GC上)的finalize()调用触发进行刷新。

        7
  •  0
  •   kohlerm    17 年前

    可以为缓存的内存使用定义一个有意义的度量。您可以计算: "retained size" . 不幸的是,计算保留大小的成本大约与完整GC一样高,因此可能不是一种选择。在某些JVM语言(clojure?)中,理论上可以确保缓存中的对象不会被外部对象引用,然后可以监视缓存的实际大小。

        8
  •  -1
  •   paulmurray    17 年前

    完成这项工作的是java.lang.ref.SoftReference。通常,您会扩展SoftReference类,以便子类包含密钥。