2017-10-13 3 views
1

저는 최근 Java Server에서 메모리 사용을 벤치마킹하고 최적화하기위한 작업을 수행하면서 메모리 누수가있는 경우이를 수정했습니다. 우리는 15G 물리적 메모리와 32G 스왑 메모리가있는 단일 머신에서 4 개의 JVM 서버를 실행합니다. 다음은 free -m 스냅 샷입니다.JVM 메모리 최적화 이해

   total  used  free   shared buff/cache available 
Mem:   15289  14786   392   1   110   342 
Swap:   32767  3776  28991 

내가 제대로 이해한다면 : -

  1. 실제 메모리의 대부분을 사용하고 스왑 메모리의 대부분은 무료입니다.
  2. 메모리 양이 실제로 버퍼링됩니다.
  3. 나는 지금 내 서버의 각 -Xmx 옵션을 설정 7G 최대 힙 크기와 실행

가상 메모리의 48기가바이트 있습니다. GC Utils의 출력은 다음과 같습니다.

$ jstat -gcutil 8317 
    S0  S1  E  O  M  CCS  YGC  YGCT FGC FGCT  GCT 
    0.00 0.00 6.97 0.22 96.77 91.89  72 8.027 33 10.975 19.002 
$ jstat -gcutil 8332 
    S0  S1  E  O  M  CCS  YGC  YGCT FGC FGCT  GCT 
    0.00 0.00 5.17 50.76 96.57 91.65 274 51.001 51 179.106 230.107 
$ jstat -gcutil 8249 
    S0  S1  E  O  M  CCS  YGC  YGCT FGC FGCT  GCT 
    0.00 2.10 80.37 69.53 96.87 92.08 421 69.478 13 56.569 126.047 
$ jstat -gcutil 23875 
    S0  S1  E  O  M  CCS  YGC  YGCT FGC FGCT  GCT 
27.91 0.00 37.07 86.29 97.59 94.60 232 7.294  2 0.030 7.324 

수동 GC 실행 후 모든 서버에서 젊은 세대와 구세대를 완전히 제거했습니다. 이제이 성격을 이해하는 데 도움이 필요합니다. 기본적으로 다음과 같이 가정합니다.

  1. 객체 장수에 따라 에덴으로 수를 생존으로 이동 -> S0 -> S1 - 서버의
  2. 세> O.
  3. 는 이전 세대> 젊은 장군은 그 전체 GC가 실행되고 있지 않음을 의미 하는가가 충분히?
  4. 또는 젊은 세대에게 개체를 수집 할 기회를 더 많이 주며 이전 공간으로 개체를 이동하는 데 지연을주기 위해 SurvivorRatio 및 NewRatio 등의 설정을 조정해야합니다.
  5. 그러나 Y 공간이 늘어남에 따라 GC가 짧아지고 응용 프로그램 처리량이 떨어지는 것을 의미합니다. 메모리를 늘려서 조정해야 할 필요가 없습니까?

Full GC는 메모리를 모두 비우므로 메모리 누수가 없으므로 GC 설정을 조정하여 메모리 사용량과 응용 프로그램 사이의 균형을 어떻게 잡을 수 있습니까? 누구든지 기계 상태 이상으로 고려하여 더 많은 방향 또는 권장을 제공 할 수 있습니까?

한마디로
JVM Details: 
Java Version: openjdk version "1.8.0_131" Server Class 
GC: Parallel Collector(Default one) 

답변

2

: 당신이 당신의 시스템을 이해하려면 기본적으로 특정 시점에서 메모리 용도로 가고는 나쁜 생각입니다. 시간이 지남에 따라 행동을 살펴 보는 것이 훨씬 더 도움이됩니다. 이렇게하려면 JConsole 또는 YourKit 또는 JProfiler와 같은 전문 프로파일 러를 사용하십시오. 반면에 Hotspot-VM의 기본값은 상당히 합리적입니다. 따라서 매우 특정한 응용 프로그램 메모리 프로필이 없으면 피델 딜에서 많은 부분을 이기지 못하고 문제에 더 많은 하드웨어를 던지면 더 많은 것을 얻을 수 있습니다.

주의, 서버가 가장 prbably underdimensioned된다 (참조 질문 4)

긴 대답 :

질문 1 :어떻게 객체가 서로 다른 메모리 영역을 통해 진행합니까? 각 개체는 에덴 공간에서 만들어집니다. 첫 번째 마이너 가비지 콜렉션 (주요 콜렉션이 트리거 됨)은 해당 오브젝트를 생존자 (충분한 공간이있는 경우) 또는 종신 재직자에게 직접 배치합니다.생존자에 이미있는 객체의 경우, 하나의 생존 공간에서 다른 영역으로 이동하고 어느 시점 (VM 내의 휴리스틱으로 결정됨)에서 종전으로 이동합니다. 항상 최소한 하나의 생존자는 항상 비어 있다는 규칙이 항상 적용됩니다.

질문 2 :젊은 사람들보다 더 큰 직업은 당신이 자주 수집하지 않는다는 것을 의미합니까? 분명히 아닙니다. Java에서 가비지 콜렉션이 거의 실행되지 않으면 더 효율적으로 작동합니다. 기본적으로 마지막 컬렉션 이후에 더 많은 객체가 삭제되면 더 많은 메모리를 한 번에 정리할 수 있으므로 컬렉션이 더 효율적입니다. gc는 full-gc를 트리거하기 전에 매우 높은 채우기 수준 (100 %에 가까운)에 도달 할 때까지 채워지도록 tenured를 고안하도록 설계되었습니다. 우리는 생산 시스템이 젊은 세대가 충분히 크기 때문에 모든 임시 할당이 에덴이나 생존자 내에서 사라지기 때문에 몇 주 동안 full-gc를 수행하지 않는다는 것을 관찰합니다. 그것과 별개로 : 모든 캐시, 스프링 빈 또는 무엇이든 항상 재임 기간에 배치됩니다.

질문 3 :메모리 소비를 최적화하기 위해 메모리 매개 변수를 조정해야합니까? 부디 : NO! 정확히 무엇을하고 있는지 알지 못하면 그 물건을 만지지 마십시오. 젊은 세대를 확대하면 응용 프로그램이 메모리 부족 오류로 인해 종료 될 수 있습니다. 그런 것들을 피델리스트로 사용하기 전에 애플리케이션의 장기적 행동에 대해 명확히해야하며, 핫스팟 VM의 경험적 방법은 매우 좋습니다. 반면에 gc 시간을 현저하게 줄일 수 있습니다. 하나의 시스템 (위에서 언급 한 시스템)에서 우리는 한 번 ~ 20 초에서 몇 분 안에 한 번에 작은 컬렉션의 감소를 보았고 조정 후에는 full-gcs에서 거의 완전한 중지를 보았습니다. 그러나 학습과 이해의 과정에서 우리의 응용 프로그램이 시간이 지남에 따라 어떻게 메모리를 거쳤는지, 우리는 많은 처형을 저지했습니다.

질문 4 :필독 대신 메모리를 늘려야합니까?에 따라 다릅니다. 귀하의 시스템은 그대로 건강하지 않습니다. 메모리를 늘리면 그 상태가 악화됩니다. 16g의 실제 메모리가있는 시스템에서 최대 7g (총 28g)의 힙을 가진 4 개의 VM을 실행 중입니다. 모든 VM이 메모리 소비량을 최대로 늘리면 스와핑이 많이 발생하여 성능을 거의 상상할 수없는 수준으로 확실히 낮 춥니 다. 나는 시나리오에서 더 많은 하드웨어를 고려할 것이다. 특히 자바 애플리케이션의 실제 소비는 대략 1.5 배의 힙 (permgen/metaspace, 스택, 코덱 및 메모리 자체가 소비하는 메모리를 추가해야한다.). 확실한 경우 응용 프로그램은 -xmx7g로 실행됩니다. 거기에서 시작할 수 있습니다 : 전체 메모리를 늘리면서 old-gen 부분을 줄이면서 절대적으로 오래된 크기가 변경되지 않도록합니다. 그러나 이것은 더 많은 하드웨어를 의미합니다.

+0

답해 주셔서 감사합니다. 그러나 무언가는 여전히 분명합니다. 전체적인 초점은 서버가 7g를 필요로하지 않는다는 것입니다. YG는 개체를 수집 할 충분한 기회를 얻지 못했고 OG는 일반적으로 좋은 일이므로 덜 자주 실행했습니다. Y 공간을 늘리면이 문제를 해결할 수 있습니다. YGCT가 증가 할 수 있습니다. 그러나 YG의 증가로 인해 OOM으로 이어질 수 있다는 점은 분명하지 않습니다. 힙 크기는 여전히 동일합니다. –

+0

마이너 컬렉션에 남아있는 요소가 있으면 OOM이 발생합니다.이 요소는 보유자에게 대피되고 보유자는 보유 할 공간이 충분하지 않습니다. 기본적으로 OOM에 관해서는 젊음은 완전히 무의미합니다. 더 큰 젊은 공간은 사소한 콜렉션을 덜 빈번하게 (그리고 전체 프로세스를보다 효율적으로) 만들 것입니다. 그러나 더 큰 청년은 상대적으로 작아서 OOM을 유발할 수 있습니다. – Jonathan

+0

@MangatRaiModi 나는 아직도 요점을 모르겠다 : 왜 당신은 전체 gcs가 더 자주 실행해야한다고 생각합니까? 보통이 영역에서 최적화 할 때 가능한 한 많이 수집 빈도를 줄이기를 원합니다. 이는 젊은뿐만 아니라 오래된 사람들에게도 적용됩니다. – Jonathan