• Java Memory 튜닝하기.

    [Original Document]

     

     

    신세대 Heap
    JDK 1.4.1에서 heap은 신세대, 구세대,
    영구세대(Permanent generation)의 3단계로 나눠진다.
    신세대는 또한 Eden과 Semi-spaces로 나뉜다. Eden과
    semi-spaces의 크기는 SurvivorRatio(생존률)에 의해 조정되며 다음과 같이 계산할 수 있다.

    Eden = NewSize – ((NewSize / ( SurvivorRatio
    + 2)) * 2)
    From space = (NewSize – Eden) / 2
    To space = (NewSize – Eden) /
    2

    NewSize는 신세대의 크기이며 -XX:NewSize 옵션을 사용해 지정할 수 있다.
    SurvivorRatio는 정수이며 1부터 매우 높은 값까지 가능하다. 신세대의 크기는 다음 옵션을 사용해 조절할 수 있다.

    -XX:NewSize
    -XX:MaxNewSize
    -XX:SurvivorRatio

    예를 들어 128MB의 신세대에서 64MB를 Eden에, 32MB를
    Semi-Space에 할당하고자 하면 NewSize와 MaxNewSize, SurvivorRatio의 값을 다음과 같이 명시할 수 있다.

    java -Xms512m -Xmx512m -XX:NewSize=128m
    -XX:MaxNewSize=128m \
    -XX:SurvivorRatio=2 application


    구세대 Heap

    구세대 또는 Tenured
    Generation는 신세대에서 승진한 오래된 객체를 가지고 있다. -Xms 매개변수를 사용해서 구세대의 최대 크기를 조정할 수
    있다.
    앞서 예를 보다 확장해서 256MB의 구세대 heap과 256MB의 신세대를 -mx 변수를 사용해서 지정할 수 있다.

    java -Xms512m -Xmx512m -XX:NewSize=256m
    -XX:MaxNewSize=256m \
    -XX:SurvivorRatio=2
    application

    신세대가 256MB를 사용하고 구세대가 다른 256MB를 사용한다. -Xms를 사용해서 초기 heap 크기를
    지정했다.

     

     

    영구세대의 Heap
    영구세대(Permanent
    generation)는 클래스 객체와 그 관련 메타 정보를 저장하는 데에 사용된다. 기본 크기는 4MB이며 -XX:PermSize와
    -XX:MaxPermSize 옵션을 사용해 설정할 수 있다.
    종종 로그 파일에서 Full GC를 볼 수 있을 텐데, 이것은 영구세대를
    확장할 때 생기는 것이다. 이런 현상은 -XX:PermSize와 -XX:MaxPermSize 옵션을 사용해서 영구세대의 heap을 크게 잡으면
    막을 수 있다. 예를 들어 다음과 같이 해보자.

    java -Xms512m -Xmx512m -XX:NewSize=256m
    -XX:MaxNewSize=256m \
    -XX:SurvivorRatio=2 -XX:PermSize=64m
    -XX:MaxPermSize=64m application

    영구세대의 컬렉션을 비활성화시키는 방법은 -Xnoclassgc 옵션을 사용하는 것이다.
    이 옵션은 클래스 객체를 컬렉션하지 못하게 하기 때문에 조심해서 사용해야 한다. 이를 사용하기 위해서는 GC가 일어나지 않을 정도로 클래스
    객체를 저장할 수 있는 영구세대의 크기를 크게 잡으면 된다. 예를 들어 다음과 같이 한다.

    java -Xms512m -Xmx512m -XX:NewSize=256m
    -XX:MaxNewSize=256m \
    -XX:SurvivorRatio=2 -XX:PermSize=128m
    -XX:MaxPermSize=128m \
    -Xnoclassgc
    application
     
     
    기본 사용법
    Java 애플리케이션은 다음 명령어로 실행될 수 있다.

    java application

    기본적으로 신세대에서 Eden은 2MB, Semi-space는 64KB가 잡혀 있다.
    구세대 heap은 5MB로 시작해서 44MB까지 확장된다. 영구세대의 기본 크기는 4MB이다.

    -Xms와 -Xms 스위치
    사용하기

    구세대의 기본 heap 크기는 -Xms와 -Xmx를 사용해서 초기값 및 최대 크기값을 변경할 수 있다.

    java -Xms <initial size> -Xmx
    <maximum size> program

    예를 들면 다음과 같다.

    java -Xms128m -Xmx512m
    application

    :XX 스위치를 사용해 새로운 Low Pause 또는 Throughput
    Collector 사용하기

    ·Low Pause Collector 사용하기
    신세대에서는
    -XX:+UseParNewGC 옵션을 사용해 Parallel Copying Collector를 활성화시킬 수 있으며, 구세대에서는 -XX:
    +UseConcMarkSweepGC를 사용해 Concurrent Collector를 활성화시킬 수 있다. 예를 들면 다음과 같다.

    java -server -Xms512m -Xmx512m
    -XX:NewSize=64m -XX:MaxNewSize=64m \
    -XX:SurvivorRatio=2 -XX:+
    UseConcMarkSweepGC \
    -XX:+UseParNewGC application

    다만 -XX:+UseParNewGC가 명시되지 않았으면 신세대는 기본적으로
    Copying Collector(http://wireless.java.sun.com/ midp/articles/garbage/참조)를 사용하게
    될 것이다. 또한 단일 CPU 시스템에서 -XX+UseParNewGC가 명시되지 않았다면 CPU의 개수가 1개이기 때문에 기본인 Copy
    Collector가 사용된다. 병렬의 정도를 증가시켜 Parallel Copy Collector를 활성화시킬 수
    있다.

    – 병렬의 정도를 조정하기
    기본적으로 Parallel Copy Collector는 CPU 개수만큼의
    쓰레드를 생성해 사용하지만 병렬의 정도를 조정해야 한다면 다음과 같이 변경할 수 있다.

    -XX:ParallelGCThreads=<desired
    parallelism>

    기본값은 CPU 개수와 동일하다. 예를 들어 신세대의 컬렉션이 4개의 병렬 쓰레드를
    사용하기 위해선 다음과 같다.

    java -server -Xms512m -Xmx512m
    -XX:NewSize=64m -XX:MaxNewSize=64m \
    -XX:SurvivorRatio=2 -XX:+UseParNewGC
    -XX:ParallelGCThreads=4 \
    -XX:+UseConcMarkSweepGC application


    – JDK 1.4.1에서 ‘promoteall’ 변경자
    모방하기

    ‘promoteall’ 변경자는 JDK 1.2.2에서 신세대의 모든 유효한 객체를 구세대로 별도의 과정 없이 곧바로
    승진시킨다. JDK 1.4.1에는 ‘promoteall’ 변경자가 없지만 보유분포(tenuring distribution)를 조정해서 비슷한
    현상을 만들 수 있다. MaxTenuringThreshold 옵션을 통해 신세대에 있는 객체가 노화되는 횟수를 조정한다. 이 옵션을 0으로
    설정하면 곧바로 구세대로 승진되는 것이다. SurvivorRatio는 20000 또는 그 이상의 높은 값으로 설정해서 신세대 Heap 크기 중
    Eden이 대부분 사용하게 한다.

    -XX:MaxTenuringThreshold=0
    -XX:SurvivorRatio=20000

    예를 들면 다음과 같다.

    java -server -Xms512m -Xmx512m
    -XX:NewSize=64m -XX:MaxNewSize=64m \
    -XX:SurvivorRatio=20000
    -XX:MaxTenuringThreshold=0 \
    -XX:+UseParNewGC -XX:+UseConcMarkSweepGC
    application


    Concurrent Collection 초기화
    조정하기

    Concurrent Collector의 백그라운드 쓰레드는 구세대의 공간 활용 비율이 기본적으로 68%인,
    -XX:CMSInitiatingOccupancy Fraction보다 높으면 시작하게 된다. 이 값은 변경할 수 있으며, 다음 옵션을 사용해서
    Concurrent Collector를 더 빨리 실행시킬 수
    있다.

    -XX:CMSInitiatingOccupancyFraction=<percent>

    예를 들면 다음과
    같다.

    java -server -Xms512m -Xmx512m -XX:NewSize=64m -XX:MaxNewSize=64m
    \
    -XX:SurvivorRatio=20000 -XX:MaxTenuringThreshold=0 \
    -XX:+UseParNewGC
    -XX:+UseConcMarkSweepGC \
    -XX:CMSInitiatingOccupancyFraction=35
    application

    ·Throughput Collector 사용하기
    신세대에서 -XX:UseParallelGC
    옵션을 사용해서 Parallel Scavenge Collector를 활성화시킬 수 있다. 구세대는 기본적으로 Mark-Compact
    Collector을 사용하기 때문에 명시할 필요가 없다.

    32비트일 때:
    java -server -Xms3072m -Xmx3072m
    -XX:NewSize=2560m \
    -XX:MaxNewSize=2560m XX:SurvivorRatio=2
    \
    -XX:+UseParallelGC application64비트일 때:
    java -server -d64
    -Xms8192m -Xmx8192m -XX:NewSize=7168m \
    -XX:MaxNewSize=7168m
    XX:SurvivorRatio=2 \
    -XX:+UseParallelGC application

    단, -XX:TargetSurvivorRatio는 신세대에서 보유하고 있는 객체를
    복사하는 데에 사용되는 보유한계이다. 큰 heap과 SurvivorRatio가 2이면 TargetSurvivorRatio의 기본값이 50이기
    때문에 survivor semi-space가 낭비될 수 있다. 이 값을 75나 90으로 조정하면 공간 활용이 극대화될
    것이다.


    – 병렬 정도 조정하기

    Parallel Scavenge Collector 또한 CPU 개수만큼
    쓰레드를 생성해 사용하지만 병렬의 정도를 조정해야 한다면 다음과 같이 변경할 수 있다.

    -XX:ParallelGCThreads=<desired
    parallelism>

    기본값은 CPU의 개수와 동일하다. 예를 들어 신세대 컬렉션을 처리하는 데에 4개의
    병렬 쓰레드를 사용하기 위해선 다음과 같이 하면 된다.

    java -server -Xms3072m -Xmx3072m
    -XX:NewSize=2560m \
    -XX:MaxNewSize=2560m XX:SurvivorRatio=2
    \
    -XX:+UseParallelGC -XX:ParallelGCThreads=4
    application


    – 성능을 위한 적응형 크기 조절

    Parallel
    Scavenge Collector는 -XX:+UseAdaptiveSizePolicy를 사용할 때 성능이 더 좋다. 신세대의 크기를 자동으로
    조정하고 최대 성능을 위한 최적화된 생존률을 설정해준다. Parallel Scavenge Collector는 항상
    -XX:UseAdaptiveSizePolicy 옵션을 사용하는 게 좋다. 예를 들면 다음과 같다.

    java -server -Xms3072m -XX:+UseParallelGC
    \
    -XX:+UseAdaptiveSizePolicy
    application

     

     

     

     

    출처 : http://blog.daum.net/bluelinu/8247868

     

     

     

     

     

    Comments

    comments

    Post Tagged with , ,

답글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다.