Print
카테고리: [ Java ]
조회수: 39013

 

1. 개요

java를 실행시킬 때, 혹은 WAS를 설치/구성 후 기동할 때 JVM옵션에 Heap, Perm 등의 설정을 넣지 않고 
운영하다 쏟아져들어오는 요청들에~ 메모리를 많이 필요료하는 로직들에 의해 OutOfMemoryError를 종종 만나시게 되는데요~
(물론 설정해둬도 날 수 있는 에러지만요..ㅎㅎ)

이 size size SIZE!! 들을 설정하지 않았을 때 대체 default 값이 얼마였길래 OOME가 났었던 걸까 궁금하셨던 분 안계신가요?
저는 무지무지 궁금했더랬습니다.

java doc에 따르면 Sun/Oracle Windows and Solaris/Linux JVMs의 default는 64MB라고 합니다. 하지만 이 값은 JVM 벤더마다 다를 수 있다~ 라고 이야기하고 있죠.
JRockit의 경우의 max heap size 계산법이 또 다르거든요..

만약...내 JVM이 최대 얼마만큼의 메모리를 사용할 수 있으려나..궁금하신 분들! 이렇게 런타임 시에 확인 가능하다고 합니다.

    : System.out.println(Runtime.getRuntime().maxMemory());


여튼..다시 본 주제로 돌아와서! default size를 확인하는 방법을 알아볼께요~

 

2. Java Default Heap/Perm Size 알아내는 방법

[Linux]
java -XX:+PrintFlagsFinal -version 2>&1 | grep -i -E 'heapsize|permsize|version'
 
[Windows]
java -XX:+PrintFlagsFinal -version 2>&1 | findstr /I "heapsize permsize version"
 
 

3. 확인 결과

 
[Linux]
            : 123MB 정도를 heap 초기치로 잡네요! max heap은 1970MB 정도이고 perm 초기값은 20MB 정도네요!
               ==> 어떻게 이렇게 계산이 되는지는 일단 확인 결과 보고 알려드리죠.ㅎㅎ
 
# java -XX:+PrintFlagsFinal -version 2>&1 | grep -i -E 'heapsize|permsize|version'

    uintx AdaptivePermSizeWeight                    = 20              {product}
    uintx ErgoHeapSizeLimit                         = 0               {product}
    uintx HeapSizePerGCThread                       = 87241520        {product}
    uintx InitialHeapSize                          := 128983616       {product}
    uintx LargePageHeapSizeThreshold                = 134217728       {product}
    uintx MaxHeapSize                              := 2065694720      {product}
    uintx MaxPermSize                               = 174063616       {pd product}
    uintx PermSize                                  = 21757952        {pd product}

java version "1.7.0_79"
 

 

   ※ java 1.8 이상을 사용하신다면,

       permsize 대신 아래처럼 metaspacesize로 적절히 대체하시어 확인하시면 됩니다! :)

 

 

[Windows]

D:\>java -XX:+PrintFlagsFinal -version 2>&1 | findstr /I "heapsize metaspacesize version"

    uintx ErgoHeapSizeLimit                         = 0                                   {product}
    uintx HeapSizePerGCThread                       = 87241520                            {product}
    uintx InitialBootClassLoaderMetaspaceSize       = 4194304                             {product}
    uintx InitialHeapSize                          := 134217728                           {product}
    uintx LargePageHeapSizeThreshold                = 134217728                           {product}
    uintx MaxHeapSize                              := 2147483648                          {product}
    uintx MaxMetaspaceSize                          = 4294901760                          {product}
    uintx MetaspaceSize                             = 21807104                            {pd product}

java version "1.8.0_111"
 
 

4. 어떻게 이렇게 초기 값을 잡게 되나요?

오라클 java 문서(http://www.oracle.com/technetwork/java/ergo5-140223.html) 에 따르면,
jvm을 server class로 실행하면 초기 heap size는 메모리의 1/64 이고, 최대 heap size는 1/4까지 늘어난다고 합니다.
 
그래서, 제가 확인했던 Linux 서버의 결과 값이 어떻게 나왔냐구요?
아래는 top 결과 입니다. 이 서버에 총 8GB의 메모리가 할당되어 있죠.
 
 
 
그렇게 해서, heap size 초기 값은 8GB의 1/64 인 123MB, 최대 값은 8GB의 1/4인 1970MB로 계산이 됩니다.
완전 쉽죠?^^
 
그럼 서버에 메모리가 32GB가 할당되어 있다면 우리우리 JVM의 default heap size는 얼마일까요~?? >_<