본문 바로가기

Monitoring Tools/Tools

tomcat jvm heap 모니터링

반응형

1. 목적 : 운영서버 "OutOfMemory" 의 잦은 발생으로 사용중인 heap 메모리를 영역 별, 세대 별 등으로 자세한 모니터링이 필요하며 모니터링을 통한 영역, 세대별의 할당 메모리 size를 튜닝 할수 있음.

 

2. JVM heap 구조 

- GC(Garbage Collection) 순서 : Eden(객체 최초 생성) → Survivor(From→To) → Old

 

3. Heap layout 할당에 영향을 주는 스위치들

 

4. New(Young) Generation 메모리 할당 공식 (참조용으로 실질 할당은 모니터링을 통한다)

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

 

5. Old Generation 메모리 할당 공식 (참조용으로 실질 할당은 모니터링을 통한다)

Old = Xmx - MaxNewSize

 

6. 모니터링

 6.1 jstat

> jstat --help
 
 invalid argument count
Usage: jstat -help|-options
       jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]
 
Definitions:
  <option>      An option reported by the -options option
  <vmid>        Virtual Machine Identifier. A vmid takes the following form:
                     <lvmid>[@<hostname>[:<port>]]
                Where <lvmid> is the local vm identifier for the target
                Java virtual machine, typically a process id; <hostname> is
                the name of the host running the target Java virtual machine;
                and <port> is the port number for the rmiregistry on the
                target host. See the jvmstat documentation for a more complete
                description of the Virtual Machine Identifier.
  <lines>       Number of samples between header lines.
  <interval>    Sampling interval. The following forms are allowed:
                    <n>["ms"|"s"]
                Where <n> is an integer and the suffix specifies the units as
                milliseconds("ms") or seconds("s"). The default units are "ms".
  <count>       Number of samples to take before terminating.
  -J<flag>      Pass <flag> directly to the runtime system.
 
 
## 예제
## jstat -옵션 -pid -시간
 
 
> jps
24546 Jps
22981 QuorumPeerMain
 

> jstat -gc 22981 3s
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT  
2048.0 2048.0  0.0   224.0  107008.0 29003.9   344064.0    5957.8   12032.0 11729.5 1280.0 1181.7     37    0.285   0      0.000    0.285
 

> jstat -gccapacity 22981 3s
 NGCMN    NGCMX     NGC     S0C   S1C       EC      OGCMN      OGCMX       OGC         OC       MCMN     MCMX      MC     CCSMN    CCSMX     CCSC    YGC    FGC
172032.0 2746880.0 212992.0 2048.0 2048.0 107008.0   344064.0  5494272.0   344064.0   344064.0      0.0 1060864.0  12032.0      0.0 1048576.0   1280.0     37     0
 

> jstat -gcutil 22981 3s
  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT  
  0.00  10.94  28.33   1.73  97.49  92.32     37    0.285     0    0.000    0.285

  - 옵션 (굵은 색은 주로 사용하는 옵션)

옵션 기능
gc 각 힙(heap) 영역의 현재 크기와 현재 사용량(Eden 영역, Survivor 영역, Old 영역등), 총 GC 수행 횟수, 누적 GC 소요 시간을 보여 준다.
gccapacity 각 힙 영역의 최소 크기(ms), 최대 크기(mx), 현재 크기, 각 영역별 GC 수행 횟수를 알 수 있는 정보를 보여 준다. 단, 현재 사용량과 누적 GC 소요 시간은 알 수 없다.
gccause -gcutil 옵션이 제공하는 정보와 함께 마지막 GC 원인과 현재 발생하고 있는 GC의 원인을 알 수 있는 정보를 보여 준다.
gcnew New 영역에 대한 GC 수행 정보를 보여 준다.
gcnewcapacity New 영역의 크기에 대한 통계 정보를 보여 준다.
gcold Old 영역에 대한 GC 수행 정보를 보여 준다.
gcoldcapacity Old 영역의 크기에 대한 통계 정보를 보여 준다.
gcpermcapacity Permanent 영역에 대한 통계 정보를 보여 준다.
gcutil 각 힙 영역에 대한 사용 정도를 백분율로 보여 준다. 아울러 총 GC 수행 횟수와 누적 GC 시간을 알 수 있다.

  - 옵션 별 항목 설명

 

6.2 jmx monitoring

  6.2.1 사용 가능한 옵션 탐색

- Download JMXterm
https://sourceforge.net/projects/cyclops-group/files/jmxterm/1.0.0/jmxterm-1.0.0-uber.jar/download
 
- Run JMXterm
> java -jar jmxterm-1.0.0-uber.jar --url localhost:<jmx listen port>
 
 
 
 
> java -jar jmxterm-1.0.0-uber.jar --url {ip}:{port}
Welcome to JMX terminal. Type "help" for available commands.
$>domain java.lang
#domain is set to java.lang
$>beans
#domain = java.lang:
java.lang:name=Code Cache,type=MemoryPool
java.lang:name=CodeCacheManager,type=MemoryManager
java.lang:name=Compressed Class Space,type=MemoryPool
java.lang:name=G1 Eden Space,type=MemoryPool
java.lang:name=G1 Old Gen,type=MemoryPool
java.lang:name=G1 Old Generation,type=GarbageCollector
java.lang:name=G1 Survivor Space,type=MemoryPool
java.lang:name=G1 Young Generation,type=GarbageCollector
java.lang:name=Metaspace Manager,type=MemoryManager
java.lang:name=Metaspace,type=MemoryPool
java.lang:type=ClassLoading
java.lang:type=Compilation
java.lang:type=Memory
java.lang:type=OperatingSystem
java.lang:type=Runtime
java.lang:type=Threading
$>quit
#bye
 
 
## 테스트

> java -jar cmdline-jmxclient-0.10.3.jar - {ip}:{port} java.lang:name=G1\ Survivor\ Space,type=MemoryPool
Attributes:
 Usage: Usage (type=javax.management.openmbean.CompositeData)
 PeakUsage: PeakUsage (type=javax.management.openmbean.CompositeData)
 MemoryManagerNames: MemoryManagerNames (type=[Ljava.lang.String;)
 UsageThreshold: UsageThreshold (type=long)
 UsageThresholdExceeded: UsageThresholdExceeded (type=boolean)
 UsageThresholdCount: UsageThresholdCount (type=long)
 UsageThresholdSupported: UsageThresholdSupported (type=boolean)
 CollectionUsageThreshold: CollectionUsageThreshold (type=long)
 CollectionUsageThresholdExceeded: CollectionUsageThresholdExceeded (type=boolean)
 CollectionUsageThresholdCount: CollectionUsageThresholdCount (type=long)
 CollectionUsage: CollectionUsage (type=javax.management.openmbean.CompositeData)
 CollectionUsageThresholdSupported: CollectionUsageThresholdSupported (type=boolean)
 Valid: Valid (type=boolean)
 Name: Name (type=java.lang.String)
 Type: Type (type=java.lang.String)
 ObjectName: ObjectName (type=javax.management.ObjectName)
Operations:
 resetPeakUsage: resetPeakUsage
  Parameters 0, return type=void
 

> java -jar cmdline-jmxclient-0.10.3.jar - {ip}:{port} java.lang:name=G1\ Survivor\ Space,type=MemoryPool Usage
05/06/2020 13:42:43 +0900 org.archive.jmx.Client Usage:
committed: 75497472
init: 0
max: -1
used: 75497472

 

 

 

7. 튜닝 (예시 이므로 참고만)

JAVA_OPTS="-Djava.awt.headless=true -Dfile.encoding=UTF-8 -server -Xms3072m -Xmx3072m -XX:NewSize=384m 

-XX:MaxNewSize=384m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:+DisableExplicitGC"

 

* Xms, Xmx를 동일하게 세팅하는 이유

 - Xms로 init 메모리를 잡고, committed 도달할 때까지 Used용량이 점차 증가하는데, 

committed에 도달시 메모리 추가할당시 시스템 부하발생 (WAS가 몇 ms가량 멈출 가능성 있음)

 - 메모리 용량은 init < used < committed < max 

 - 보통 운영시스템에서 Xms와 Xmx를 동일하게 지정하는 이유는 init와 max사이에서 used 메모리가 committed까지 사용하게 되면, 

  신규 메모리 공간을 요구하는데 이 때 약 1초가량 jvm이 메모리 할당 중 멈춰버리는 경우가 있다. 

  그래서 Xms와 Xmx를 동일하게 주고 메모리를 확보한 상태에서 jvm을 기동시키곤 한다. 

반응형

'Monitoring Tools > Tools' 카테고리의 다른 글

haproxy 모니터링(haproxy stats)  (0) 2021.03.17