performance - Java 堆瓶颈 - 如何确定原因?

标签 performance jakarta-ee heap-memory profile

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

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

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

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

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

最佳答案

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

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

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

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

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

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

关于performance - Java 堆瓶颈 - 如何确定原因?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3334232/

相关文章:

php - 如何测量用 PHP 编写的代码的速度?

spring - spring 3.1.2 中使用注释的国际化不起作用

javascript - Node.js 堆内存不足

performance - Chrome DevTools : Triangle warning icon on Timeline view,是什么?

java - Oracle数据库: using Char(X) or Numeric(X) instead of Date

eclipse - 将 Java Web EE Netbeans 项目导入 Eclipse

java - 如何在JPA中混合继承类型

c++ - 内联一个操作堆上数据的函数

java - 在 hosteurope 服务器上的 Jenkins 中运行 android gradle 脚本时出现堆内存问题

android - Android 中的 "string constant"操作是什么?