我的内存中有一个很大的缓存(使用com.google.common.cache.LoadingCache
)。使用 Scheduler 会在 10 分钟后刷新,如下所示:
ScheduledExecutorService refresher = Executors.newSingleThreadScheduledExecutor();
refresher.scheduleWithFixedDelay(
new Runnable() {
public void run() {
for (String key : cache.asMap().keySet()) {
cache.refresh(key);
}
}
}, 0, 10, TimeUnit.MINUTES);
我面临的问题是 - 每 10 分钟后老一代空间就会出现一个巨大的峰值。我假设发生这种情况是因为正在进行刷新,并且旧对象没有像创建新对象那样快地被清除。这可以在下图中看到。 (注:此图显示了 CMS GC,但我使用 G1GC 得到了相同的结果)。
我可以采取哪些步骤来优化这个特定问题?我可以使用 CMS 或 G1GC,但这些尖峰必须被压平。原因是,Full GC 正在启动,应用程序正在进入Stop The World GC
.
我可以做些什么来优化缓存的代码以更有效地刷新它,这样就不会出现突然的峰值?
我假设发生这种情况是因为正在进行刷新,并且旧对象没有像创建新对象那样快地被清除。
使用分配分析器可以帮助测试该假设。
我可以采取哪些步骤来优化这个特定问题?我可以使用 CMS 或 G1GC,但这些尖峰必须被压平。原因是,Full GC 正在启动,应用程序将进入 Stop The World GC。
Full GC 通常表明收集器的并发部分跟不上分配速率。但要验证,您应该检查 GC 日志以了解 Full GC 的原因。
您可以尝试降低 IHOP、为并发 GC 工作提供额外的 CPU 核心或调整刷新任务的节奏,以便它们在 10 分钟间隔内更加分散。
您还应该检查混合集合的 GC 启发式日志(假设 G1GC)是否能够为混合集合选择任何区域。如果它直接从年轻回收到完整 GC,而没有任何混合回收,那么由于缓存的分配模式,其他一些启发式方法可能会出现问题。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)