在阅读了一些有关 jvm 内存的文章后(这里,这里,这里,其他我忘了...),我期望我的 java 进程的驻留集大小大致等于当前堆空间容量。数字不是这么说的,它似乎大致等于最大堆空间容量:
驻留集大小:
# echo 0 $(cat /proc/1/smaps | grep Rss | awk '{print $2}' | sed 's#^#+#') | bc
11507912
# ps -C java -O rss | gawk '{ count ++; sum += $2 }; END {count --; print "Number of processes =",count; print "Memory usage per process =",sum/1024/count, "MB"; print "Total memory usage =", sum/1024, "MB" ;};'
Number of processes = 1
Memory usage per process = 11237.8 MB
Total memory usage = 11237.8 MB
Java 堆
# jmap -heap 1
Attaching to process ID 1, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 24.55-b03
using thread-local object allocation.
Garbage-First (G1) GC with 18 thread(s)
Heap Configuration:
MinHeapFreeRatio = 10
MaxHeapFreeRatio = 20
MaxHeapSize = 10737418240 (10240.0MB)
NewSize = 1363144 (1.2999954223632812MB)
MaxNewSize = 17592186044415 MB
OldSize = 5452592 (5.1999969482421875MB)
NewRatio = 2
SurvivorRatio = 8
PermSize = 20971520 (20.0MB)
MaxPermSize = 85983232 (82.0MB)
G1HeapRegionSize = 2097152 (2.0MB)
Heap Usage:
G1 Heap:
regions = 2560
capacity = 5368709120 (5120.0MB)
used = 1672045416 (1594.586769104004MB)
free = 3696663704 (3525.413230895996MB)
31.144272834062576% used
G1 Young Generation:
Eden Space:
regions = 627
capacity = 3279945728 (3128.0MB)
used = 1314914304 (1254.0MB)
free = 1965031424 (1874.0MB)
40.089514066496164% used
Survivor Space:
regions = 49
capacity = 102760448 (98.0MB)
used = 102760448 (98.0MB)
free = 0 (0.0MB)
100.0% used
G1 Old Generation:
regions = 147
capacity = 1986002944 (1894.0MB)
used = 252273512 (240.5867691040039MB)
free = 1733729432 (1653.413230895996MB)
12.702574926293766% used
Perm Generation:
capacity = 39845888 (38.0MB)
used = 38884120 (37.082786560058594MB)
free = 961768 (0.9172134399414062MB)
97.58628042120682% used
14654 interned Strings occupying 2188928 bytes.
- 我的期望错了吗?我应该期待什么?
- 我需要堆空间能够在峰值期间增长(以避免非常缓慢的完整 GC),但我希望在其余时间内驻留集大小尽可能低,以造福服务器上运行的其他进程。有没有更好的方法来实现这一点?
Linux 3.13.0-32-generic x86_64
java version "1.7.0_55"
Running in Docker version 1.1.2
Java 正在运行 elasticsearch 1.2.0:
/usr/bin/java -Xms5g -Xmx10g -XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=20 -Xss256k -Djava.awt.headless=true -XX:+UseG1GC -XX:MaxGCPauseMillis=350 -XX:InitiatingHeapOccupancyPercent=45 -XX:+AggressiveOpts -XX:+UseCompressedOops -XX:-OmitStackTraceInFastThrow -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintClassHistogram -XX:+PrintTenuringDistribution -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime -Xloggc:/opt/elasticsearch/logs/gc.log -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt elasticsearch/logs/heapdump.hprof -XX:ErrorFile=/opt/elasticsearch/logs/hs_err.log -Des.logger.port=99999 -Des.logger.host=999.999.999.999 -Delasticsearch -Des.foreground=yes -Des.path.home=/opt/elasticsearch -cp :/opt/elasticsearch/lib/elasticsearch-1.2.0.jar:/opt/elasticsearch/lib/*:/opt/elasticsearch/lib/sigar/* org.elasticsearch.bootstrap.Elasticsearch
实际上有 5 个 elasticsearch 节点,每个节点位于不同的 docker 容器中。所有节点的内存使用量大致相同。有关索引的一些统计数据:
size: 9.71Gi (19.4Gi)
docs: 3,925,398 (4,052,694)