我的程序是普通的java程序,执行时间比较长,有的时候会莫名奇妙的死掉,好像是陷入了死循环。
但是从程序的输出来看,死掉的位置根本没有循环!死掉的位置不定,而且死掉的时候耗费大量的cpu时间。我的调用方式如下:
java -Xdebug -Xrunjdwp:transport=dt_socket,server=y
,suspend=n,address=5432 com.ninemax.stat.EveryDay >>/tmp/everyday.txt 2>&1程序死掉的时候,通过top看到如下情况:
68 processes: 67 sleeping, 1 running, 0 zombie, 0 stopped
CPU states:  cpu    user    nice  system    irq  softirq  iowait    idle
           total    6.0%    0.0%   18.9%   0.0%     0.0%    5.7%   69.2%
           cpu00    0.0%    0.0%    0.0%   0.0%     0.0%    5.6%   94.4%
           cpu01   24.2%    0.0%   75.8%   0.0%     0.0%    0.0%    0.0%
           cpu02    0.0%    0.0%    0.0%   0.0%     0.0%    7.2%   92.8%
           cpu03    0.0%    0.0%    0.0%   0.0%     0.0%   10.2%   89.8%
Mem:  2061224k av, 1962864k used,   98360k free,       0k shrd,   19076k buff
                   1204052k actv,  363332k in_d,   30592k in_c
Swap: 10482372k av,    8468k used, 10473904k free                 1707836k cache
d  PID USER     PRI  NI  SIZE  RSS SHARE STAT %CPU %MEM   TIME CPU COMMAND
32470 root      15   0 16672  16M   232 S    24.9  0.8  2331m   1 java
    1 root      15   0   104   92    48 S     0.0  0.0   0:19   2 init
该java进程占用了所有的 cpu 01 的时间而且系统时间非常的多。然后使用 
jdb -connect com.sun.jdi.SocketAttach:hostname=localhost,port=5432
连接,竟然连接不上。我怀疑是垃圾收集出错了,因为出错的位置不定。各位有什么好的方法?另外 System.out.println 在运行一段时间后就不重定向到 /tmp/everyday.txt 文件了,也不知道输出到哪里去了,但是 System.err.println 却有效,真是奇怪?

解决方案 »

  1.   

    你用的什么操作系统?
    不重新定向的话,是不是文件大小已经达到了unix下的最大文件尺寸?
    你的内存快用光了,好像gc没有工作啊。
    连接不上可能是由于端口堵塞,怀疑由于运行时间过长,而且一直占用大量的cpu和内存,
    致使gc无法启动,而一些坏的链接和过期的进程仍然占用系统资源。
    我瞎猜的
      

  2.   

    操作系统是 Linux,内存没有问题,操作系统会尽可能的用内存来做缓冲,只要swap区占用不大就可以了。文件可没有打到linux下的最大文件尺寸,只有几百K而已,System.err.println的输出还是有效的啊。
    连接不上好像是jvm不监听 5432 端口了,我也怀疑是那内存和gc的问题,所以现在使用 -Xms16M -Xmx512 -verbose:gc 来看看了。
    谢谢各位
      

  3.   

    我仔细追踪了 System.out 对象在程序中的变化,发现都是同一个对象,但是在第一次循环后就不输出了,导致 gc 垃圾收集的信息也无法输出,真实奇怪。java 版本
    java version "1.4.2_05"
    Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_05-b04)
    Java HotSpot(TM) Client VM (build 1.4.2_05-b04, mixed mode)操作系统 
    Linux db1 2.4.21-4.ELsmp #1 SMP Fri Oct 3 17:52:56 EDT 2003 i686 i686 i386 GNU/Linux
      

  4.   

    换了jdk好像解决了 System.out 的输出问题,有待观察。
    新的JDK
    java version "1.4.2_05"
    Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_05-b04)
    BEA WebLogic JRockit(TM) 1.4.2_05 JVM R24.4.0-1 (build ari-38120-20041118-1131-l
    inux-ia32, Native Threads, GC strategy: parallel)
      

  5.   

    使用 JRockit 后,只有 GC的信息输出到 System.out 了,其他的 log4j 打印的信息统统没有了。
    本次执行正常,估计和内存参数调整有关。
    考虑到以前碰到的java程序的死锁的不确定性,需要多运行几次。
      

  6.   

    分析GC最开始和最后的输出信息
    [memory ] 8.390-8.401: GC 16384K->2614K (16384K), 11.000 ms
    [memory ] 135183.520-135183.562: GC 49200K->11118K (49200K), 42.000 ms
    占用内存是逐步增加的,在jvm中调用了外部命令,有的时候也会死锁在这里。
      

  7.   

    上次执行的最后的GC信息:
     [memory ] 135082.128-135082.182: GC 35936K->17787K (35936K), 54.000 ms
    换用最新的 1.4.2.09 jdk 试验一下,看看System.out.pritnln是否会有类似问题。
      

  8.   

    换用了 jdk 14.2.-09 ,结果一样的,System.out 不输出了,这次连GC的输出都看不到了。
      

  9.   

    内存占用真是很大,看不到GC的输出,只能从top看看
    --------------------------------------------------------------------------
     10:12:56  up 5 days, 17:35,  2 users,  load average: 0.65, 0.49, 1.06
    1 processes: 1 sleeping, 0 running, 0 zombie, 0 stopped
    CPU states:  cpu    user    nice  system    irq  softirq  iowait    idle
               total    0.0%    0.0%    0.0%   0.0%     0.0%    5.2%   94.7%
               cpu00    0.0%    0.0%    0.0%   0.0%     0.0%    2.5%   97.4%
               cpu01    0.0%    0.0%    0.0%   0.0%     0.0%    7.5%   92.4%
               cpu02    0.0%    0.0%    0.0%   0.0%     0.0%   11.0%   88.9%
               cpu03    0.0%    0.0%    0.0%   0.0%     0.0%    0.0%  100.0%
    Mem:  2061224k av, 2047328k used,   13896k free,       0k shrd,  168072k buff
                       1480144k actv,  175684k in_d,   34220k in_c
    Swap: 10482372k av,       0k used, 10482372k free                 1373696k cache
    d  PID USER     PRI  NI  SIZE  RSS SHARE STAT %CPU %MEM   TIME CPU COMMAND
      350 root      15   0  289M 289M 10636 S     0.0 14.3   0:56   2 java
      

  10.   

    我仔细追踪了 System.out 对象在程序中的变化,发现都是同一个对象,但是在第一次循环后就不输出了,导致 gc 垃圾收集的信息也无法输出,真实奇怪。
    ----------------------
    代码...
      

  11.   

    代码无法贴出来,抱歉。
    最近一次运行的结果:
    [memory ] 392.107-392.124: GC 16384K->4021K (16384K), 17.000 ms
    ......
    [memory ] 244486.697-244486.801: GC 92204K->46992K (92204K), 103.929 ms
    可以看到内存的占用是非常的大,超出了默认的 -Xmx 16M 的设置。System.out的问题不再追踪,本问题结束。