当运行 JVM 的 docker 容器达到内存限制时会发生什么?



假设,一个docker容器在具有16G RAM,2核CPU的服务器中运行JVM,以下是容器的内存限制:

mem_limit: 14G
max_mem: 13G
threads: 1
max_pool_size: 20

max_mem是 JVM 使用的最大堆大小,mem_limit是容器使用的最大内存。我试图理解以下事情:

  1. 当 JVM 达到max_mem限制时会发生什么?
  2. 当容器到达它时会发生什么mem_limit
  3. 它是否在有或没有 OOM 错误日志消息的情况下重新启动?我们在哪里可以看到这些日志?
  4. max_mem后我们应该为容器留多少内存?
  5. 线程如何影响内存限制?

1. 当 JVM 达到max_mem限制时会发生什么?
它必须崩溃。如果你有一个实时恢复,或者在docker-swarm或kubernetes上,它会迅速启动另一个容器。

2. 当集装箱到达mem_limit时会发生什么?
它必须报告并崩溃。答案与上述相同。

3. 它是否在有或没有 OOM 错误日志消息的情况下重新启动?
它给出 OOM 错误。问题1,错误日志在容器内,所以你需要登录死容器并查看日志。问题2,错误日志来自码头工人,码头工人日志必须显示它。Docker 日志也会显示容器日志。

4. 我们在哪里可以看到这些日志?
在上面的问题中回答

5. max_mem后我们应该为容器留多少内存?
为您的应用程序进行内存模型设计,并添加缓冲区并据此限制您的容器。如果容器由于 OOM 而不断崩溃,请确保修复应用程序代码

6. 线程如何影响内存限制?
线程是一个运行器,它使用内存或磁盘中的资源。线程数阻塞内存不是因为它们的数量很大,而是因为它们在创建时携带的内存中的本机数据。


希望我已经回答了你的问题。

查看文档,似乎有一个memswap_limit选项,所以我认为可以安全地假设将使用交换。它可能会崩溃,因为 jvm 擅长这一点,但是,我想它只是运行缓慢。

线程本身不会变慢,但由于交换而导致的读/写速度缓慢,它基本上会成为瓶颈。

您的最大mem问题很难回答,而不会弄乱它。你可能会在某个地方找到有人推荐10-20%的净空,但你真的应该尝试找到你自己的最佳点。

注意:14gb ram 对于单个容器来说已经很多了。如果可能,应考虑将工作负载分布在多个容器上。Docker run 允许您使用 --scale arg 扩展容器,而 kubernetes 等编排平台可以为您管理流程。

最新更新