kubectl top pod ,kubectl exec 后执行 top 和 Arthas 看到的 java 进程对比
kubectl top pod 的内存使用量计算
container_memory_rss 表示容器的常驻内存集(Resident Set Size),即实际使用的物理内存量。
container_memory_cache 表示容器使用的缓存内存。
container_memory_usage_bytes 表示容器当前使用的内存量,包括常驻内存和缓存,**缓存部分往往会有很多处于空闲**。
container_memory_mapped_file 表示容器使用的映射文件内存。
container_memory_swap 表示容器使用的交换内存量。
container_memory_working_set_bytes 表示容器的工作集,即容器当前活跃使用的内存量,不包括缓存。
container_memory_max_usage_bytes 表示容器历史上使用过的最大内存量。
container_memory_failcnt 表示容器内存失败计数,即无法分配所需内存的次数。
container_memory_failures_total 表示容器内存分配失败的总次数。
# 下面部分值可以在 pod 中 /sys/fs/cgroup/memory/memory.stat 里获得
total_active_file: 表示活跃文件内存使用量
total_cache: 表示当前pod缓存内存量
total_rss: 表示当前应用进程实际使用内存量
total_inactive_anon: 表示匿名不活跃内存使用量
total_active_anon: 表示匿名活跃内存使用量,jvm堆内存使用量会被计算在此处
total_inactive_file: 表示不活跃文件内存使用量
容器当前使用内存量: container_memory_usage_bytes = total_cache + total_rss
容器当前使用缓存内存: total_cache = total_inactive_file + total_active_file
kubectl top pod 得到的内存使用量,并不是 cadvisor 中的 container_memory_usage_bytes,而是 container_memory_working_set_bytes,计算方式为:
container_memory_usage_bytes = container_memory_rss + container_memory_cache + kernel memory
container_memory_working_set_bytes = container_memory_usage_bytes – total_inactive_file(未激活的匿名缓存页)
container_memory_working_set_bytes
= container_memory_usage_bytes - total_inactive_file
= total_cache + total_rss - total_inactive_file
= total_inactive_file + total_active_file + total_rss - total_inactive_file
= total_active_file + total_rss
即:container_memory_working_set_bytes = total_active_file+ total_rss,其中 total_rss 为应用真实使用内存量,正常情况下该指标数值稳定,重点关注 total_active_file上
Linux系统为了提高文件读取速率,会划分出来一部分缓存内存,即 cache 内存,这部分内存有个特点,当应用需要进行io操作时,会向Linux申请一部分内存,这部分内存归属于操作系统,当应用io操作完毕后,操作系统不会立即回收;
当操作系统认为系统剩余内存不足时(判断依据未深究),才会主动回收这部分内存。
这部分内存属于操作系统,jvm无任何管理权限,故也不会把这部分内存计算到JVM中。container_memory_working_set_bytes 指标升高一部分是应用本身JVM内存使用量增加,另一部分就是进行了io操作,total_active_file升高;该指标异常一般都是应用进行了io相关操作。
container_memory_working_set_bytes 是容器真实使用的内存量,也是limit限制时的 oom 判断依据
kubectl exec 后执行 top 的计算
在 Docker 容器中使用 top 命令查看 Java 进程的内存使用情况时,你可能会发现显示的内存使用量比通过 JVM 工具查看的要多。
这是因为 top 命令显示的是进程的虚拟内存使用情况,包括了进程使用的库、代码、数据等。而 JVM 工具显示的是 Java 进程实际使用的堆内存大小。
JAVA进程内存 = JVM进程内存 + heap内存 + 永久代内存 + 本地方法栈内存 + 线程栈内存 + 堆外内存 + socket 缓冲区内存 + 元空间
# linux 内存和JAVA堆中的关系
RES = JAVA正在存活的内存对象大小 + 未回收的对象大小 + 其它
VIART= JAVA中申请的内存大小,即 -Xmx -Xms + 其它
其它 = 永久代内存+ 本地方法栈内存+线程栈内存 +堆外内存 +socket 缓冲区内存 +JVM进程内存
总结
因为3个命令或工具的统计方式不一样,所以大致关系如下:
kubectl top pod > kubectl exec 后执行 top > arthas 看到的 java 进程
参考
http://www.xuyasong.com/?p=1781
https://blog.csdn.net/qq_34468174/article/details/130643948

浙公网安备 33010602011771号