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 |
---|