2016-08-07 4 views
-1

자바 GC에서 이상한 동작이 발생했습니다.자바 가비지 컬렉터 이상한 행동

최대 힙이 1GB 인 응용 프로그램이있어서 GC 오버 헤드 한도를 초과하는 오류가 발생했습니다.

다음은 jmap -heap의 출력입니다.

Heap Usage: 
PS Young Generation 
Eden Space: 
    capacity = 37224448 (35.5MB) 
    used  = 34328776 (32.73847198486328MB) 
    free  = 2895672 (2.7615280151367188MB) 
    92.2210478446853% used 
From Space: 
    capacity = 1572864 (1.5MB) 
    used  = 786432 (0.75MB) 
    free  = 786432 (0.75MB) 
    50.0% used 
To Space: 
    capacity = 1572864 (1.5MB) 
    used  = 0 (0.0MB) 
    free  = 1572864 (1.5MB) 
    0.0% used 
PS Old Generation 
    capacity = 1072168960 (1022.5MB) 
    used  = 13918336 (13.2735595703125MB) 
    free  = 1058250624 (1009.2264404296875MB) 
    1.2981476352383863% used 

Heap Configuration: 
    MinHeapFreeRatio   = 40 
    MaxHeapFreeRatio   = 70 
    MaxHeapSize    = 1610612736 (1536.0MB) 
    NewSize     = 1572864 (1.5MB) 
    MaxNewSize    = 536870912 (512.0MB) 
    OldSize     = 1072168960 (1022.5MB) 
    NewRatio     = 2 
    SurvivorRatio   = 8 
    MetaspaceSize   = 21807104 (20.796875MB) 
    CompressedClassSpaceSize = 1073741824 (1024.0MB) 
    MaxMetaspaceSize   = 17592186044415 MB 
    G1HeapRegionSize   = 0 (0.0MB) 
그래서 우리는 다음과 같은 매개 변수를 사용하여 GC를 조정;

newSize와와 MaxNewSize

-XX:NewSize=512 
-XX:MaxNewSize=512 
-XX:SurvivorRatio=16 
-XX:NewRatio=1 

는 매크로 블럭으로 설정하기로했다.

그러나이 구성으로 다음 힙 맵을 얻습니다.

Heap Usage: 
PS Young Generation 
Eden Space: 
    capacity = 524288 (0.5MB) 
    used  = 200200 (0.19092559814453125MB) 
    free  = 324088 (0.30907440185546875MB) 
    38.18511962890625% used 
From Space: 
    capacity = 524288 (0.5MB) 
    used  = 98304 (0.09375MB) 
    free  = 425984 (0.40625MB) 
    18.75% used 
To Space: 
    capacity = 524288 (0.5MB) 
    used  = 0 (0.0MB) 
    free  = 524288 (0.5MB) 
    0.0% used 
PS Old Generation 
    capacity = 1072168960 (1022.5MB) 
    used  = 522704656 (498.49000549316406MB) 
    free  = 549464304 (524.0099945068359MB) 
    48.752078776837564% used 

Heap Configuration: 
    MinHeapFreeRatio   = 40 
    MaxHeapFreeRatio   = 70 
    MaxHeapSize    = 2147483648 (2048.0MB) 
    NewSize     = 1572864 (1.5MB) 
    MaxNewSize    = 1572864 (1.5MB) 
    OldSize     = 1072168960 (1022.5MB) 
    NewRatio     = 1 
    SurvivorRatio   = 16 
    MetaspaceSize   = 21807104 (20.796875MB) 
    CompressedClassSpaceSize = 1073741824 (1024.0MB) 
    MaxMetaspaceSize   = 17592186044415 MB 
    G1HeapRegionSize   = 0 (0.0MB) 

지금 에덴 빈 용량은 0.5MB이지만 단지 38 %에있는 이전에 92 %였다 사용하고, 용량 35메가바이트이었다. Old Gen 활용도가 이전에 약 2 %였던 50 %까지 증가했습니다.

누구든지 GC가 이와 같이 작동하는 이유를 설명해주십시오.

+0

* "NewSize 및 MaxNewSize는 MB로 설정되어야합니다."* - 그런데 왜 MB로 설정하지 않습니까? – the8472

+0

이미 설정했습니다. 그러나 앞서 언급 한 행동의 이유를 알고 싶습니다. –

+0

총 사용 가능한 시스템 메모리는 얼마이고 -Xms 및 -Xmx에 대해 설정 한 값은 무엇입니까? – ravthiru

답변

0

나는 마침내 그 이유를 발견 할 수있었습니다.

JVM이 객체에 대해 힙 할당을 시도하면 해당 TLAB (스레드 로컬 할당 버퍼)의 사용 가능한 크기를 먼저 확인하고 충분하지 않으면 확장을 시도합니다. 에덴 공간의 나머지 크기가 TLAB 확장에 충분하지 않은 경우 JVM은 에덴 공간 자체를 찾습니다. Eden 공간의 나머지 크기가 충분하지 않으면 JVM이 Old Gen 공간에서 객체를 직접 할당합니다.

NewGen 크기가 더 작 으면 Eden 공간뿐만 아니라 두 생존자 공간도 작습니다 (일반적으로 8 또는 16 번). 따라서 JVM이 에덴 공간에서 공간을 할당하는 경우에도 해당 객체가 몇 가지 소규모 콜렉션에서 생존 할 수 있는지를 관리합니다. 생존자 공간이 오버플로되어 OldGen 공간으로 이동합니다.