5

我们在高峰时间遇到严重的应用程序问题,应用程序变得非常非常慢,当我检查 AppDynamics 矩阵时,我的堆内存已满,并且每分钟都会启动 GC,这使得它非常非常慢。这是我的java(tomcat)的配置

OS version is Redhat 5 Linux

java version "1.6.0_05" 64Bit

Java 选项是-Djava.awt.headless=true -Xmx2048m -XX:MaxPermSize=256m -XX:+HeapDumpOnOutOfMemoryError -XX:+UseConcMarkSweepGC -XX:+DisableExplicitGC

每分钟花费的主要 GC 收集时间 (ms)

在此处输入图像描述

CMS Old Gen 使用量(以 MB 为单位)

在此处输入图像描述

以 MB 为单位的 Eden 空间

在此处输入图像描述

有什么建议为什么par eden space和老一代会遇到强硬路线?

更新

这是最近 12 小时的堆使用情况和主要 GC 收集(绿点)的图片,GC 非常高,3:00AM to 7:00AM但是当我重新启动应用程序时,7:30AM一切都很好并且应用程序响应时间非常快,为什么重新启动解决了所有问题?

在此处输入图像描述

欢呼!4GB Heap 解决了问题

4GB 后每分钟 (ms) 的主要 GC 收集时间花费(零次主要 GC)

在此处输入图像描述

4GB 堆后 CMS Old Gen 使用量(以 MB 为单位)

在此处输入图像描述

4GB 堆后以 MB 为单位的 Par Eden 空间

在此处输入图像描述

4

3 回答 3

3

每分钟一次主要的 GC 似乎一点也不麻烦。通常它需要大约半秒,所以这是你整体 CPU 使用率的 1/120。繁重的应用程序负载会导致更多的内存分配也是很自然的。显然,您正在分配一些存在一段时间的对象(可能是缓存)。

我的结论:展示的 GC 行为并不能证明您的应用程序的内存分配有问题。

更新

我已经更仔细地查看了您的图表(不幸的是,它们很难阅读)。您每分钟没有一个 GC;您每分钟有 60的主要 GC,这意味着它一直在发生。这看起来确实是个大麻烦事实上,在这些情况下,由于“超过 GC 时间百分比阈值”,您通常会得到 OOME。请注意,您使用的 CMS 收集器实际上比默认的要慢;它的优点只是它不会“阻止世界”。它可能不是您的最佳选择。但是您确实看起来要么存在内存泄漏,要么存在程序设计中的一般问题。

于 2013-08-16T15:00:12.123 回答
2

当 JVM 达到堆最大大小时,会更频繁地调用 GC 以防止 OOM 异常。在这种情况下不应发生正常的程序执行。当分配了一个新对象并且 JVM 无法获得足够的可用空间时,就会调用 GC。这可能会推迟对象分配过程,从而降低整体性能。在这种情况下,垃圾收集不会同时发生,您不会从 CMS 收集器中受益。试着玩一下CMSInitiatingOccupancyFraction,它的默认值是 90% 左右。将此参数设置为较低的值,将在应用程序达到堆最大值之前强制进行垃圾收集。因此 GC 将与应用程序并行工作,而不会与之冲突。查看文章开始并发收集周期

于 2013-08-16T15:49:24.140 回答
1

您是否一直在等待 GC 处理删除未使用的引用?在您的应用程序中是否有一些地方您知道从那时起不再使用对重量级对象的引用,但它没有被手动清空?也许在正确的位置手动将如此重的对象设置为 null 可以防止它们增长直到它们到达堆的末尾......

于 2013-08-16T15:16:46.850 回答