2009-11-04 8 views
0

나는 그들 사이에서 상호 작용하는 많은 컴퓨터에서 자바 프로그램을 실행 중이다. 컴퓨터가 몇 시간 (2 ~ 5 시간) 후에 (스레드가 교착 상태에 빠지기 시작하면 메시지가 손실되기 시작합니다. 처음 1 시간 정도 걸리면 훌륭한 메시지가 표시됩니다.자바 힙 공간과 메시지 손실

너무 많은 메모리를 사용하고 있기 때문에 의문의 여지가 있습니다. 그래서 리눅스에서 실행하고있어이 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 힙 크기의 상태를보고 정기적으로 로그인하여 메모리 사용의 추세에 대한 통찰력을 얻을 수 있습니다. 이 로그에서 그래프를 플롯하고 이상이 있는지 확인할 수 있습니다. (, BTW 퍼즐 패턴은 일반 쓰레기 행동을 수집하는 것입니다.)

// 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는 메인 처리 스레드가 처리 할 수있는 작업 큐에 넣습니다.