我们使用IBM JDK 1.4.2在AIX上的Websphere Portal Server 5.1上运行一个相当复杂的应用程序作为portlet。在我们的生产系统中,我可以在详细的GC日志中看到奇怪的行为。经过一段时间的正常行为后,系统可以开始快速分配更大和更大的块。系统开始花费>完成每个GC需要1000毫秒,但是分配的块很快,分配失败之间只有30毫秒的差距。
我认为这可能是基础设施而不是我们的应用程序代码。如果在一个循环中它是一个错误的字符串连接,我们会期望比1024的块更不规则的增长。如果它是StringBuffer或ArrayList增长,我们会看到块大小加倍。增长让我想到了日志缓冲或其他东西。在我们的应用程序中,我无法想到任何分配甚至1 MB,更不用说14.今天我在刷新到磁盘之前寻找在内存中备份的日志记录,但是在此期间GC崩溃的日志记录量远远不够MB范围。
显然,问题在于过多的内存分配而不是垃圾收集,垃圾收集正在尽力跟上。有些东西正在分配一个大块,并且试图以太小的增量低效地增长它。
任何想法在系统负载时可能导致所有这些?有人看到过与Portal Server类似的东西吗?
注意:对于任何感兴趣的人来说,开始看起来原因是偶尔但是巨大的数据库查询。似乎罪魁祸首是Hibernate或JDBC驱动程序。
答案 0 :(得分:2)
不确定可能导致问题的原因,但这里有一个关于如何调查更多内容的想法: IBM JDK非常棒,因为它可以配置为在收到SIGQUIT信号时执行堆转储 在之前的项目中,它不是我们的JDK,但只要我们有内存问题需要调查,我们就会使用它。
以下是启用heapdump的方法: http://publib.boulder.ibm.com/infocenter/javasdk/v1r4m2/index.jsp?topic=/com.ibm.java.doc.diagnostics.142j9/html/enabling_a_heapdump.html
然后有一个名为heaproot的工具,可以让你看到这些转储中的内容。
找到对象的类型会引起你的罪魁祸首。
答案 1 :(得分:1)
根据您使用的IBM JDK的确切版本,有多种选项可用于跟踪“大量分配”。差异主要在于实现,结果是在进行一定大小的分配时记录Java堆栈跟踪(这应该可以帮助您追踪罪魁祸首)。
“Sovereign”1.4.2 SR4 +: http://www-01.ibm.com/support/docview.wss?uid=swg21236523
“J9”1.4.2(如果Java在-Xj9选项下运行): 您需要为同一目的获取JVMPI / JVMTI代理,我现在找不到这个代理的链接。
答案 2 :(得分:0)
只有一个提示......一旦我们有一个项目由于堆碎片而遭遇重大GC问题(Websphere和IBM JDK)。最后,我们添加了一个JDK开关来强制堆压缩。
Sun JDK不会占用碎片堆,但IBM JDK会因内存/ GC处理不同而产生影响。
试一试......我记不起魔术开关了。