【问题标题】:Guava cache memory leakGuava 缓存内存泄漏
【发布时间】:2013-05-13 08:43:32
【问题描述】:

我正在使用 guava 库 14.0.1 来实现缓存服务(一个包含用于放置和获取值的 servlet 的 Web 应用程序)。 Web 应用程序部署在包含 1GB RAM(谷歌后端)的机器上。写入和读取操作的数量巨大(每秒 50 个查询)。

即使在达到最大大小限制后,机器上使用的 RAM 量也会继续增加。我怀疑内存泄漏。

以下是我用来创建缓存的代码

Cache cache = CacheBuilder.newBuilder()
                .expireAfterWrite(1, TimeUnit.DAYS)
                .initialCapacity(2000000)
                .maximumSize(3800000)
                .concurrencyLevel(50)
                .recordStats()
                .build();

使用检索值

Map result = cache.getAllPresent(keys);

使用将值放入缓存中

cache.put(key, value);

我可以使用什么设置来阻止 RAM 使用量超过限制。

【问题讨论】:

标签: java guava


【解决方案1】:

查询率很低,所以我会尝试减少并发(可能是 1-4)并减少最大大小。鉴于您机器的资源有限,我怀疑 1K 到 100K 的最大大小更合适,具体取决于您的对象有多大。

来自 Java 文档

public CacheBuilder maximumSize(long size) 指定缓存可以包含的最大条目数。

如果您的条目是 1 KB,那么仅此缓存就需要大约 4 GB。

我说速率很低的原因是调用这个集合通常需要一微秒(即你的限制可能是每秒一百万,并发量为 1)

【讨论】:

  • 大小不是问题。我正在存储Long's。当我达到指定的最大大小时,消耗的 RAM 量为 950MB。但它并不止于此。它一直在增加。
  • @Rakesh maximumSize 不是绝对的,因为清理是摊销的(来自 javadoc:“如果请求 maximumSize 或 maximumWeight,则每次缓存修改时可能都会驱逐条目”;强调我的)。这就是为什么您实际上可以拥有比指定最大值更多的条目,以及为什么您不希望并发级别太高,因为这会在 Cache 中创建尽可能多的段,其中最大大小必须有点强制执行。 50 个请求/秒的并发级别 50 不是必需的。
猜你喜欢
  • 1970-01-01
  • 2023-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-22
  • 2015-06-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多