我有一个运行在tomcat上的web应用程序,最大堆大小设置为8GB。
如果没有用户登录到应用程序中,非可清理内存(即垃圾收集后留下的内存)会相当低,约为1GB。在这种情况下,我看到持续增长了约4GB的内存,然后垃圾收集器运行并将内存再次降至约1GB。如果没有用户登录,则此模式将继续。
GC日志显示完整的GC需要11秒,这是相当长的时间,而与之相比,小GC只需要约1秒:
如果没有用户登录到应用程序中,非可清理内存(即垃圾收集后留下的内存)会相当低,约为1GB。在这种情况下,我看到持续增长了约4GB的内存,然后垃圾收集器运行并将内存再次降至约1GB。如果没有用户登录,则此模式将继续。
GC日志显示完整的GC需要11秒,这是相当长的时间,而与之相比,小GC只需要约1秒:
2017-02-14T15:30:44.553+0530: 591.922: [GC (Allocation Failure) [PSYoungGen: 1501051K->631966K(1833472K)] 2392189K->1523112K(3030016K), 1.5100144 secs]
...[Times: user=1.49 sys=0.01, real=1.51 secs]
2017-02-14T15:31:20.335+0530: 627.705: [GC (Allocation Failure) [PSYoungGen: 1553054K->595007K(1842176K)] 2444200K->1570521K(3038720K), 1.3050284 secs]
...[Times: user=1.27 sys=0.04, real=1.31 secs]
2017-02-14T15:33:33.682+0530: 761.052: [GC (Allocation Failure) [PSYoungGen: 1516095K->556800K(1842176K)] 2491609K->1596474K(3038720K), 1.6957154 secs]
...[Times: user=1.67 sys=0.03, real=1.69 secs]
2017-02-14T15:33:35.378+0530: 762.748: [Full GC (Ergonomics) [PSYoungGen: 556800K->365446K(1842176K)] [ParOldGen: 1039673K->1196476K(2018304K)] 1596474K->1561923K(3860480K), [Metaspace: 70472K->70472K(1114112K)], 11.2779843 secs]
...[Times: user=11.13 sys=0.09, real=11.28 secs]
2017-02-14T15:34:56.232+0530: 843.602: [GC (Allocation Failure) [PSYoungGen: 1286534K->216613K(1842176K)] 2483011K->1609875K(3860480K), 1.4938761 secs]
...[Times: user=1.45 sys=0.05, real=1.50 secs]
由于在GC期间所有其他线程都被挂起,因此如果用户在Full GC期间尝试访问Web应用程序,则服务器将不会响应。 是什么触发了这次Full GC?
根据日志,小型GC事件是由于分配失败引起的,而Full GC是由于人体工学
引起的。 这是什么意思?
还有大量的空闲堆空间,我想延迟Full GC的发生,直到由于小型GC没有显着的内存减少。 在这种情况下,我能阻止Full GC的发生吗?
我的VM参数如下:
export CATALINA_OPTS="$CATALINA_OPTS -Xms512m -Xmx8192m -XX:+UseConcMarkSweepGC"
System.gc()
调用。 我曾看到 CMS 收集器变得有些疯狂,并在调用System.gc()
后始终执行停止整个世界的 full GC。 您可以通过-XX:+DisableExplicitGC
JVM 选项使 GC 忽略此类调用。 - Mick MnemonicSystem.gc()
。在正常操作中,GC日志没有任何这样的条目。 - Lahiru ChandimaSystem.gc()
调用。尝试上述选项或更安全的变体可能值得一试,该变体不会忽略调用,而是调用CMS收集器而不是完整GC:-XX:+ExplicitGCInvokesConcurrent
。 - Mick Mnemonic