【问题标题】:Java heap bottleneck - how to identify the cause?Java 堆瓶颈 - 如何确定原因?
【发布时间】:2010-07-26 11:04:56
【问题描述】:

我有一个在 JBoss 上运行的 J2EE 项目,最大堆大小为 2048m,这在负载测试下给出了奇怪的结果。我已经对堆和 cpu 使用率进行了基准测试,并收到了以下结果(系列 1 是堆使用率,系列 2 是 cpu 使用率):

似乎堆被正确使用并在 A 周围正确收集垃圾。然而,当它到达 B 时,似乎存在某种瓶颈,因为有可用的堆空间,但它永远不会打破这个想象线。同时,在 C 处,cpu 使用率急剧下降。在此期间,我们还会收到“OutOfMemoryError(超出 GC 开销限制)”,这对我来说没有多大意义,因为有可用的堆空间。

我的猜测是存在某种瓶颈,但我什至无法想象到底是什么。您建议如何寻找问题的原因?我分析了内存使用情况并注意到一个类有很多实例(大约一百万),但这些实例的总大小相当小(如果我没记错的话大约 50MB)。

编辑:服务器专用于此应用程序,并且给定的 CPU 使用率仅适用于 JVM(在 JVM 之外不应有任何显着的 CPU 使用率)。内存使用仅用于堆,不包括 permgen 空间。这个问题是可以重现的。我主要关心的是围绕 B 遇到的限制,对此我还没有找到合理的解释。

结论:原来这是由一堆长时间运行的 SQL 查询同时调用造成的。返回的 ResultSets 也非常大,可能解释了 OOME。我仍然没有合理的解释为什么 B 似乎有一些限制。

【问题讨论】:

    标签: performance jakarta-ee heap-memory profile


    【解决方案1】:

    从错误消息看来,JVM 正在使用并行清道夫算法进行垃圾收集。当a lot of time is spent on GC, but not a lot of the heap is recovered 时,该消息与OOME 错误一起转储。

    Sun 的文档没有具体说明是否将消耗的总时间的 98% 读取为进程 CPU 利用率的 98% 或 CPU 本身的 CPU 利用率。无论哪种情况,我都必须得出以下推论(信息有限):

    • 垃圾收集器或 JVM 进程没有足够的 CPU 利用率,很可能是由于其他进程同时消耗 CPU。
    • 垃圾收集器没有足够的 CPU 使用率,因为它是一个低优先级线程,并且 JVM 中的另一个内存密集型(但不是 CPU 密集型)线程正在同时工作,导致无法 de-分配内存。

    基于上述推论(所有推论,一个或一个都不是真的),就用户而言,将您获得的图表与应用程序的运行时行为相关联是值得的。换句话说,您可能会发现确定其他进程是否被启动(当您的问题发生时)或正在运行的应用程序部分(再次,当问题发生时)很有用。

    无论如何,上面引用的页面确实提供了一个选项来禁用 GC 算法使用的 GC 开销限制。

    编辑:如果问题周期性出现,并且可以重现,则可能是内存泄漏,否则(即偶尔发生),您最好调整 GC 算法或甚至改变它。

    【讨论】:

    • 第一个要点对我来说没有意义,因为 cpu 使用率下降。第二个似乎是合理的,但我仍然不明白为什么内存使用量似乎达到了某种无法通过的最大值?我宁愿不更改 GC 开销限制,因为我觉得它只会解决症状而不是原因。
    • 如果您的图表仅报告 JVM 的 CPU 使用率,而不是其他进程,那么第一点是有意义的。至于 GC 开销限制的标志,那只是禁用开销;你不能改变它。谈到第二点,如果你能确定你是否达到了高水位线,这可能会有所帮助。我的意思是,该图很可能没有描述整个堆,并且可能只是其中的一部分(它是否也包括 permgen?)。
    • 好的,我明白你对第一点的意思。此图仅用于 JVM 的 CPU 使用情况,系统专用于此应用程序。该图不包括 permgen,所以您是否建议它可能是导致 OOME 的 permgen 空间?随着时间的推移,什么会影响 permgen 空间,过去我在 permgen 上遇到的唯一问题是加载和卸载类?
    • 作为附加说明:即使堆上有可用内存,我也可以理解导致 OOME 的 permgen 空间不足,但它仍然不能解释堆上的“高水位标记”。
    • 好吧,分配给堆的 2G 也包括 permgen。 permgen 空间可以单独指定,但这会影响其他对象可用的内存量。随着越来越多的类被加载,占用的 permgen 空间量可能会增加(直到指定的最大值,超过该最大值会出现 permgen 空间错误)。我认为,根据您提供的信息,您现在应该查看各代 JVM 堆消耗了多少内存,还应该查看其他进程的 CPU 使用情况,重点是前者。
    【解决方案2】:

    如果我想知道“瓶颈”在哪里,我只会得到一些堆栈截图。没有必要怀疑、猜测和扮演侦探。他们只会告诉你。

    通常内存问题和性能问题是齐头并进的,所以如果你解决了性能问题,你也将解决内存问题(虽然不确定)。

    【讨论】:

      猜你喜欢
      • 2010-11-04
      • 1970-01-01
      • 2020-07-15
      • 1970-01-01
      • 2014-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-31
      相关资源
      最近更新 更多