2009-11-04 78 views
0

我在许多计算机上运行java程序,它们之间进行交互。经过几个小时(2-5小时)后,计算机开始出现故障(线程开始陷入僵局,消息开始迷失 - 如果考虑到在第一个小时内运行得很好,那么特别的东西就会消失)。java堆空间和消息丢失

我有一个怀疑,这是因为我使用了太多的内存。我在Linux上运行,所以这就是top相关的输出:

PID USER  PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 
30376 username 18 0 976m 132m 6804 S 0 4.0 0:05.60 java 
  1. 这个问题似乎高?
  2. 其他的想法应该为什么这些错误会发生将受到欢迎...

回答

4

可能发生的另一件事是,你运行了连接。昨天刚刚发生在我的一位同事身上。

ulimit -n会告诉你可以打开多少个文件句柄; netstat -at会告诉你有多少个插座已打开。当第二个号码接近第一个时,尝试打开连接将开始失败。

在这种特殊情况下,当连接在使用后仍然在OPEN_WAIT中时,强制垃圾回收(Runtime.gc())有所帮助。

3

您可以通过观察JVM堆大小的状态,并定期记录它得到的内存使用情况的趋势的洞察力。从这些日志中,您可以绘制图表并查看是否有异常情况。 (顺便说一句,一个锯齿模式是正常的垃圾收集行为。)

// Memory status 
    Runtime  runtime = Runtime.getRuntime(); 
    final long totalMem = runtime.totalMemory(); 
    final long freeMem = runtime.freeMemory(); 
    if (log.isDebugEnabled()) { 
     log.debug("Memory free=" + freeMem + 
       " used=" + (totalMem - freeMem) + 
       " total=" + totalMem); 
    } 
0

可能的问题:

  1. 资源(套接字,数据库等)没有被正确关闭
  2. 内存泄漏(集合中的被关押的引用,不关闭资源)
  3. 微妙的并发错误的是很少出现(这会在几小时后显示)
  4. 在您有机会读取或获取大于缓冲区的消息之前,套接字缓冲区上的消息将被覆盖,通常通过使用线程尽快读取套接字ata继续并将其放在主处理线程可处理的工作队列中