2012-08-10 7 views
2

나는 3 개 스레드와 다중 스레드 응용 프로그램을 실행하고 있습니다 :는 메모리 누수 자바 OutOfMemoryError를 벡터에 목록

  • 메인 쓰레드 - 벡터 목록 저장소는
  • AdderThread 개체 -이 벡터 목록
  • RemoverThread에 개체를 추가 - vectorList.clear() 메서드로 객체 제거 (동기화)

응용 프로그램은 잘 실행되지만 몇 시간 후에 OutOfMemoryError가 발생합니다.

힙 덤프를 생성하고 모든 메모리를 사용하는 vectorList 클래스를 표시하는 eclipse MAT를 사용하여 분석했습니다.

clear은 개별 객체가 차지하는 무료 메모리입니까?

해결 방법?

+3

당신의'remove' 메쏘드가 호출 되었습니까? 벡터가 비어 있는지 확인하기 위해'remove' 메쏘드가 반환되기 전에 벡터의 크기를 출력하는 로그를 추가 할 수 있습니까? – assylias

+0

예 clear()를 호출하면 Size가 0으로 인쇄됩니다. 나는 심지어 System.gc()를 사용하고있다. 문을 3 초 동안 반복하면 같은 오류가 발생합니다. – User1234

답변

9

작업을 해제하는 것보다 빠르게 작업을 추가하는 경우 벡터가 메모리 한도로 증가함에 따라 OutOfMemoryError가 발생합니다.

작업 대기열에 벡터를 사용하는 대신 동시성 라이브러리에서 BlockingQueue를 사용하는 것이 좋습니다.

BlockingQueue<Work> queue = new ArrayBlockingQueue<>(MAX_TASKS_WAITING); 

AdderThread calls queue.put(work); // blocks if the queue is full 

RemoverThread call queue.take(); // blocks if there is nothing to do. 

실제로 작업 대기열과 스레드 풀을 결합하므로 ExecutorService를 사용하는 것이 훨씬 간단합니다. 집행자에게 작업을 제출하면 처리됩니다. 이렇게하면 RemoverThread를위한 코드를 작성할 필요가 없습니다.

+0

감사합니다. BlockingQueue를 사용하여 구현하려고합니다. 그러나 clear() 메서드는 개별 객체가 차지하는 메모리를 삭제하지 않습니다. 각 개별 개체에는 2 개의 해시 맵이 있습니다. tempList-> vectorList.clear() -> tempList – User1234

+1

프로세스를 완전히 제거하면 clear()를 호출 할 필요가 없습니다. 일부 작업을 삭제하려면 지우기를 호출하십시오. 예 : 대기중인 작업의 길이를 제어 할 수 없기 때문입니다. 대기열을 사용하면 절대로 절망해서는 안됩니다. –

+1

clear()는 배킹 배열에서 모든 요소를 ​​제거합니다. 그러나 배열 자체는 그대로 남아 있습니다. 매우 커지면 빈 어레이가 OOM의 원인이 될 수 있습니다. 배열은 최대 2^31 -1 개의 요소를 가질 수 있습니다. 32 비트 JVM에서는 8GB를 나타냅니다. –