JVM 如何获取当前容器的资源限制?
- 如果 cpu 核心数目少于等于 8,则 GC 线程数量和 CPU 数一致
- 如果 cpu 核心数大于 8,则前 8 个核,每个核心对应一个 GC 线;其他核,每 8 个核对应 5 个 GC 线程
./jdk1.8.0_144/bin/java -XX:+UseG1GC -XX:+ParallelRefProcEnabled Main
然后查看 GC 线程数目:
$ jstack $pid | grep 'Parallel GC Threads' | wc -l38
然后使用 +PrintFlagsFinal 看下参数:一算就知道物理机器有 56 个核心(8+(56-8)*5/8=38)
$ ./jdk1.8.0_144/bin/java -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal -version | grep ParallelGCThreadsuintx ParallelGCThreads =38 {product}
看来 jdk8u144 并无法读取容器配额。
./jre1.8.0_191/bin/java -XX:+UseG1GC -XX:+ParallelRefProcEnabled Main$ jstack $pid | grep 'Parallel GC Threads' | wc -l4
查看实际参数:
$ ./jre1.8.0_191/bin/java -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal -version | grep ParallelGCThreadsuintx ParallelGCThreads =4 {product}
$ ./jre1.8.0_191/bin/java -XX:+UnlockDiagnosticVMOptions -XX:+PrintContainerInfo -versionOSContainer::init: Initializing Container SupportPath to /memory.limit_in_bytes is /sys/fs/cgroup/memory/memory.limit_in_bytesMemory Limit is: 10737418240Path to /cpu.cfs_quota_us is /sys/fs/cgroup/cpu,cpuacct/cpu.cfs_quota_usCPU Quota is: 400000Path to /cpu.cfs_period_us is /sys/fs/cgroup/cpu,cpuacct/cpu.cfs_period_usCPU Period is: 100000Path to /cpu.shares is /sys/fs/cgroup/cpu,cpuacct/cpu.sharesCPU Shares is: 681CPU Quota count based on quota/period: 4CPU Share count based on shares: 1OSContainer::active_processor_count: 4Path to /cpu.cfs_quota_us is /sys/fs/cgroup/cpu,cpuacct/cpu.cfs_quota_usCPU Quota is: 400000Path to /cpu.cfs_period_us is /sys/fs/cgroup/cpu,cpuacct/cpu.cfs_period_usCPU Period is: 100000Path to /cpu.shares is /sys/fs/cgroup/cpu,cpuacct/cpu.sharesCPU Shares is: 681CPU Quota count based on quota/period: 4CPU Share count based on shares: 1OSContainer::active_processor_count: 4……java version "1.8.0_191"Java(TM) SE Runtime Environment (build 1.8.0_191-b12)Java HotSpot(TM) 64-Bit Server VM (build 25.191-b12, mixed mode)
可以看到,获取的内存限制、可用 CPU 数目都是对的了。
$ cat /proc/mounts | grep -E -w '(cpu|memory)'cgroup /sys/fs/cgroup/memory cgroup ro,nosuid,nodev,noexec,relatime,memory 0 0cgroup /sys/fs/cgroup/cpu,cpuacct cgroup ro,nosuid,nodev,noexec,relatime,cpu,cpuacct 0 0
对于内存:
$ cat /sys/fs/cgroup/memory/memory.limit_in_bytes10737418240
其一,可以通过 quota/period 来算:对于 cpu 资源:
$ cat /sys/fs/cgroup/cpu,cpuacct/cpu.cfs_period_us #单CPU总时间片配额,微秒100000$ cat /sys/fs/cgroup/cpu,cpuacct/cpu.cfs_quota_us #时间片内,容器可占用的CPU时间400000
也可以通过 cpu.shares 来获取:比如上面就表示分配了 4 核。
$ cat /sys/fs/cgroup/cpu,cpuacct/cpu.shares681
不过这个值是 cpu 占用份额,无法根据这个算出来可用 cpu 数量,所以基本没用。
使用 jdk 8u191 或更新版本就完事了。
点击阅读原文查看微服务引擎产品