2012-09-17 2 views
2

내 응용 프로그램이 16 개의 프로세서와 64GB의 RAM이있는 서버에서 올바르게 올바르게 실행됩니다. 여러 프로세스가 있고 프로세스에 최대 힙을 8GB로 제한하려고합니다.동시 표시 스윕 수집이 자주 발생하지 않음

제 문제는 생산자 - 소비자 패턴의 일부 형태가 있고 생산 속도를 제한해야하거나 오래된 세대의 가비지 수집이 너무 드물게 발생하기 때문에 메모리가 부족하다는 것입니다.

  • 응용 프로그램을 모니터링 할 때 4 시간 동안 실행 한 후 ParNEW에서 7 분, ConcurrentMarkSweep에서 0.775 초를 보냈습니다.
  • 내 힙 직업은 최대 6GB까지 올라간 다음 1GB로 떨어지고 나서 천천히 6GB까지 올라간 다음 다시 내려갑니다. 싸이클은 어떻게 더 자주 조금을 실행하기 위해 동시 마크 스윕을 강제 할 수, 내 메모리 직업의 90 %가 CMS 이전 세대에 의해 주어진 것을 볼 수 있습니다 약 10 분 정도 JVisualVM 통해

의입니까? 내 응용 프로그램은 테라코타 또는 일관성 등의 이벤트 중심의 처리 및 데이터 분할을 위해 설계 응용 프로그램 서버의 위에서 실행 이후


@PeterLawrey의 의견은 매우 관련이있다. 기본 구현에는 이벤트 처리를위한 대기열 처리 시스템이 포함되어있을 가능성이 큽니다.

문제는 힙 크기를 제한하는 것이 해결책이되지 않는다는 것입니다. 경험 한 바에 따르면 더 자주 가비지 수집을하는 대신 응용 프로그램에서 메모리가 부족하기 때문입니다.

+2

전체 GC는 항상 OOME을 가져 오기 전에 실행되므로 CMS 실행 빈도는 중요하지 않습니다. 너가 말하는게 이거니? 또는 "메모리 부족"으로 다른 것을 의미합니까 –

+2

왜 더 자주 수집해야한다고 생각합니까? 왜 그것이 기억을 잃을 것이라고 생각하니? 당신은 어떤 행동을 OOM으로 분류합니까? – Matt

+0

생산자의 생산 제한을 힙 크기에 부과하는 것이 가능한 최선의 선택인지 확실하지 않습니다. 이러한 매개 변수는 생성 된 객체의 절대 최대 값을 반영하도록 명시 적으로 지정해야합니다. 편집 : @ Peter Lawrey의 대답을 참조하십시오 –

답변

2

낮은 숫자로 설정하면 initiating occupancy으로 자주 수집 할 수 있습니다.

-XX:CMSInitiatingOccupancyFraction=<nn> 
+0

자세히 설명해 주시겠습니까? – Edmondo1984

3

본인은 생산 속도를 제한 할 필요가 또는 당신이 바운드 형식의 큐를 사용하는 경우이 일어날 것

메모리

부족하게됩니다. 생산자가 소비자의 비율을 초과하면 메모리가 부족할 때까지 대기열이 제한없이 커질 수 있습니다. 제작자를 제한하면 대기열이 적절한 크기로 유지됩니다.

이 문제를 해결하는 간단한 방법은 대기열이 너무 길어질 때 제작자를 지연시키는 것입니다.

private final BlockingQueue<Task> tasks = new ArrayBlockingQueue<Task>(1000); 

// the producer slows when the queue length gets too long. 
tasks.offer(newTask, 1, TimeUnit.HOURS); 

이렇게하면 큐가 너무 길지는 않지만 프로듀서가 불필요하게 느려지지 않습니다.

BTW : ArrayBlockingQueue를 사용하면 링크 된 대기열과 비교하여 생성되는 쓰레기 수를 줄일 수 있습니다.

무제한 대기열이 정말로 필요한 경우 필자가 작성한 라이브러리를 사용할 수 있지만 상대적으로 낮은 수준입니다. Java Chronicle 생산자는 소비자보다 앞서 메인 메모리의 크기보다 커질 수 있습니다. 디스크 공간의 크기로만 제한됩니다.

관련 문제