代码之家  ›  专栏  ›  技术社区  ›  David Plumpton

WebSpherePortal Server的奇怪垃圾收集行为

  •  4
  • David Plumpton  · 技术社区  · 16 年前

    我们正在使用IBMJDK1.4.2在AIX上的WebSpherePortalserver5.1上运行一个相当复杂的应用程序作为portlet。在我们的生产系统上,我可以在详细的GC日志中看到奇怪的行为。经过一段正常的行为之后,系统可以开始快速地分配越来越大的块。系统开始花费1000毫秒来完成每个GC,但块的分配速度非常快,分配失败之间只有30毫秒的间隔。

    • 每个分配失败都比上一个稍大一些整数x 1024字节。例如,您可能有5 MB,然后过一会儿5 MB+17*1024。
    • 这可以持续10分钟。
    • 在停止之前,块的大小往往会增长到8到14 MB。
    • 它是一个四核系统,我假设它现在花费95%的时间做GC,其中三个核心等待另一个核心完成GC。10分钟。哎哟。
    • 显然,此时系统性能会下降。
    • 我们有JSF、Hibernate&jdbc、Web服务调用、log4j输出等。

    我将其解释为可能是基础结构,而不是我们的应用程序代码。如果它是一个坏的循环中的字符串连接,那么我们希望它比1024块更不规则地增长。如果是stringbuffer或arraylist增长,我们会看到块大小加倍。这种增长让我想到了日志缓冲或其他一些事情。在我们的应用程序中,我想不出任何可以分配1 MB的东西,更不用说14 MB了。今天,在刷新到磁盘之前,我寻找在内存中备份的日志记录,但是在这个GC振荡期间,日志记录语句的数量远没有接近MB的范围。

    显然,问题在于内存分配过多,而不是垃圾收集,垃圾收集只是尽其所能地跟上。一些东西正在分配一个大的块,并试图以非常小的增量低效地增长它。

    有什么想法,当系统处于负载状态时,可能是什么导致了这一切?有人看到类似的门户服务器吗?

    注意:对于任何感兴趣的人来说,看起来原因是偶尔会出现大量的数据库查询。似乎罪魁祸首不是休眠,就是JDBC驱动程序。

    3 回复  |  直到 6 年前
        1
  •  1
  •   Mike Tunnicliffe    16 年前

    根据您使用的IBMJDK的确切版本,有多种跟踪“大分配”的选项。差异主要是在实现中,结果是在某个大小上进行分配时记录日志Java堆栈跟踪(这将有助于跟踪罪犯)。

    “主权”1.4.2 SR4+: http://www-01.ibm.com/support/docview.wss?uid=swg21236523

    “J9”1.4.2(如果Java在-XJ9选项下运行): 为了同样的目的,您需要获得一个jvmpi/jvmti代理,我现在找不到这个代理的链接。

        2
  •  2
  •   Nicolas C    16 年前

    不确定是什么导致了这个问题,但下面是关于如何进一步调查的一个想法: IBMJDK非常好,因为它可以配置为在收到sigquit信号时进行堆转储。
    在以前的一个项目中,它不是我们的JDK,但是每当我们有内存问题需要调查时,我们都会使用它。

    以下是启用堆转储的方法: http://publib.boulder.ibm.com/infocenter/javasdk/v1r4m2/index.jsp?topic=/com.ibm.java.doc.diagnostics.142j9/html/enabling_a_heapdump.html

    然后有一个名为heaproot的工具,它允许您查看这些转储文件中的内容。

    找到对象的类型应该会导致你找到罪犯。

        3
  •  0
  •   ReneS    16 年前

    只是暗示…曾经有一个项目由于堆碎片而遭受了严重的GC问题(WebSphere和IBMJDK)。最后,我们添加了一个JDK开关来强制堆压缩。

    sun jdk不能有一个碎片堆,但是ibm jdk可以,这是由于内存/gc处理的不同。

    试一试……我记不起魔法开关了。