云其它

关注公众号 jb51net

关闭
首页 > 网站技巧 > 服务器 > 云和虚拟化 > 云其它 > k8s容器内存与JVM内存

k8s之容器内存与JVM内存解读

作者:傅里叶、

这篇文章主要介绍了k8s之容器内存与JVM内存,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

容器内的 Java 应用可能会发生两种类型的 OOM 异常,

从容器来看

container_memory_working_set_bytes代表容器真实使用的内存量,也是判断超过limit的限制,超过limit则会导致oom;

container_memory_working_set_bytes = container_memory_usage_bytes - total_inactive_file(不活跃缓冲页);

container_memory_usage_bytes = container_memory_rss(进程实际使用的物理内存)+container_memory_cache(页面缓存)+kernel memory;

container_memory_cache = total_active_file + inactive_file;

从jvm来看

进程实际使用的物理内存container_memory_rss = JVM内存(堆栈元空间)+直接内存+其他(文件描述符、GC消耗等等);

容器真实使用的内存量container_memory_working_set_bytes = JVM内存(堆栈元空间)+直接内存+其他(文件描述符、GC消耗等等)+container_memory_cache(页面缓存)+kernel memory;

而预留内存又=直接内存+其他(文件描述符、GC消耗等等)+container_memory_cache(页面缓存)+kernel memory;

综上,容器真实使用的内存为 JVM内存(堆栈元空间)+ 预留内存(直接内存+文件描述符、GC消耗等 + 活跃的缓存页 + kernel memory)

一种解决 JVM 内存超限的方法

可以让 JVM 自动感知 docker 容器的 cgroup 限制,从而动态的调整堆内存大小。JDK8u131 在 JDK9 中有一个很好的特性,即 JVM 能够检测在 Docker 容器中运行时有多少内存可用。

为了使 jvm 保留根据容器规范的内存,必须设置标志 -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap。

注意:

如果将这两个标志与 Xms 和 Xmx 标志一起设置,那么 jvm 的行为将是什么?

-Xmx 标志将覆盖-XX:+ UseCGroupMemoryLimitForHeap 标志。

MaxDirectMemorySize

-XX:MaxDirectMemorySize=size用于设置New I/O(java.nio) direct-buffer allocations的峰值,-XX:MaxDirectMemorySize 没显式配置的时候,NIO direct memory 可申请的空间的上限就是 -Xmx 减去一个 survivor space 的预留大小。

如果不配置 -XX:MaxDirectMemorySize 并配置 -Xmx5G,则 默认 MaxDirectMemorySize 也将是 5G-survivor space 区,并且应用程序的总堆+直接内存使用量可能会增长到 5G + 5G = 10 G

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文