提问者:小点点

容器无法启动:内存不足,无法继续 Java 运行时环境


我们有一个在Java 8上运行的企业应用程序。构建部署环境

它一直工作得很好,直到一周前,在一次成功的管道运行后,其中一个服务器上的2个应用程序实例停止工作,并出现以下错误:

There is insufficient memory for the Java Runtime Environment to continue.
Cannot create GC thread. Out of system resources.

这两个实例在另一台服务器上运行良好。相比之下,容器无法在此服务器上启动。

该错误伴随以下信息:

可能的原因:系统物理RAM或交换空间不足,进程正在启用CompressedOops的情况下运行,Java堆可能阻止了本机堆的增长。

可能的解决方案:

  • 减少系统上的内存负载
  • 增加物理内存或交换空间
  • 检查交换后备存储是否已满
  • 减小Java堆大小(-Xmx/-Xms)
  • 减少Java线程数
  • 减少Java线程堆栈大小(-Xs)
  • 使用-XX:ReservedCodeCacheSize设置更大的代码缓存=

我们尝试过:

  1. 添加更多交换内存。服务器有8GB的RAM,而我们尝试从4GB交换到9GB。
  2. 玩堆大小 Xms

以下是记忆

free -mh
              total        used        free      shared  buff/cache   available
Mem:           15Gi       378Mi        12Gi       1.0Mi       2.9Gi        14Gi
Swap:           9Gi          0B         9Gi

我有几个相关工件的链接。其中包括完整的docker日志输出以及故障服务器和操作服务器上的docker信息的输出。

这就是docker ps -a给我们的:

:~$ docker ps -a
CONTAINER ID   IMAGE                                                                                  COMMAND                  CREATED        STATUS                    PORTS                                       NAMES
d29747bf2ad3   :a7608a838625ae945bd0a06fea9451f8bf11ebe4   "catalina.sh run"        10 hours ago   Exited (1) 10 hours ago                                               jbbatch
0951b6eb5d42   :a7608a838625ae945bd0a06fea9451f8bf11ebe4   "catalina.sh run"        10 hours ago   Exited (1) 10 hours ago                                               jbapp

我们现在已经没有主意了,因为我们已经尝试了几乎所有关于堆栈溢出的解决方案。我们遗漏了什么?


共2个答案

匿名用户

我看到您的Docker映像使用Ubuntu 22.04 LTS作为其基础。最近,在此 LTS 版本之上重建了基本的 Java 映像,这在较旧的 Docker 运行时上引起了很多问题。这很可能就是您正在经历的。它与内存无关,而是与Docker与用作基本映像的较新Linux版本不兼容有关。

操作服务器的 Docker 服务器版本 20.10.10,而故障服务器的版本为 20.10.09。不兼容问题已在 Docker 20.10.10 中完全修复。有关不兼容问题的更多技术细节,请参阅此处。

解决方案是将出现故障的服务器至少升级到Docker 20.10.10。

匿名用户

我也有同样的错误。的输出

# docker info

是:

....
Security Options:
 seccomp
  WARNING: You're not using the default seccomp profile
  Profile: /etc/docker/seccomp.json
....

这个问题通过把

  security_opt:
    - seccomp:unconfined

在docker-comp. yml中用于服务并删除和重新创建容器

docker rm <container_name>
docker-compose up -d <service_name>

也许调整/etc/docker/seccomp.json也能得到同样的结果——我试过了,但失败了。