Docker启动容器报错,提示:unable to allocate file descriptor table - out of memory
启动命令:
docker run --name sentinel -p 8858:8858 -td bladex/sentinel-dashboard
完整错误日志:
[root@Sakura sentinel]# docker run --name sentinel -p 8858:8858 -td bladex/sentinel-dashboard
7795ded48d9cc96758ea372e73e611de28dd099bfd43cb442ca3386063d61652
[root@Sakura sentinel]# docker logs sentinel
INFO: Sentinel log output type is: file
INFO: Sentinel log charset is: utf-8
INFO: Sentinel log base directory is: /root/logs/csp/
INFO: Sentinel log name use pid is: false
library initialization failed - unable to allocate file descriptor table - out of memory#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00007f2dbbc5d884, pid=1, tid=0x00007f2da45f5700
#
# JRE version: Java(TM) SE Runtime Environment (8.0_202-b08) (build 1.8.0_202-b08)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.202-b08 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# C [libc.so.6+0x36884] abort+0x244
#
# Core dump written. Default location: /bladex/sentinel/core or core.1
#
# An error report file with more information is saved as:
# /bladex/sentinel/hs_err_pid1.log
#
# If you would like to submit a bug report, please visit:
# http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
个人理解应该是这种java应用,在JVM启动时需要限制下分配的内存,尤其是虚拟机内存不充裕的情况下。
可能的解决方法,修改命令:
docker run --name sentinel -p 8858:8858 -td -m 512m --memory-swap 1g -e JAVA_OPTS="
-server
-XX:+UseG1GC
-Xmx1024m
-Xms512m
-XX:+UnlockExperimentalVMOptions
-XX:+UseCGroupMemoryLimitForHeap
-XX:MaxRAMPercentage=70.0
-XX:NewRatio=2
-XX:+PrintGCDetails
-XX:+PrintHeapAtGC
-Xloggc:/data/logs/gc.log
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/data/logs/heapdump.hprof " --ulimit nofile=65535:65535 bladex/sentinel-dashboard
参数解释:
docker run
参数
--name sentinel
:为容器指定名称sentinel
。-p 8858:8858
:将宿主机的 8858 端口映射到容器的 8858 端口。-td
:后台运行容器并分配一个伪终端。-t
是为容器分配一个伪终端,-d
是在后台运行容器。-m 512m
:限制容器使用的最大内存为 512MB。--memory-swap 1g
:设置容器内存加交换空间的限制为 1GB。-e JAVA_OPTS="..."
:设置环境变量JAVA_OPTS
,其值包含多个 JVM 参数。--ulimit nofile=65535:65535
:设置容器内进程可以打开的最大文件描述符数,软硬限制都为 65535。bladex/sentinel-dashboard
:使用的 Docker 镜像。
JAVA_OPTS
中的 JVM 参数
-server
:启用 Java 服务模式,适用于服务器应用的性能优化。-XX:+UseG1GC
:使用 G1 垃圾收集器(Garbage First Garbage Collector),适用于大多数服务端应用的默认垃圾收集器。-Xmx1024m
:设置 JVM 的最大堆内存大小为 1024MB。-Xms512m
:设置 JVM 的初始堆内存大小为 512MB。-XX:+UnlockExperimentalVMOptions
:启用实验性 JVM 选项。-XX:+UseCGroupMemoryLimitForHeap
:启用在容器环境中基于 cgroups 限制来配置 JVM 堆内存大小。-XX:MaxRAMPercentage=70.0
:设置 JVM 堆内存使用的最大比例为可用内存的 70%。-XX:NewRatio=2
:设置新生代与老年代的堆内存比例为 1:2,即新生代占堆内存的 1/3,老年代占 2/3。-XX:+PrintGCDetails
:启用详细的垃圾收集日志。-XX:+PrintHeapAtGC
:在垃圾收集前后打印堆内存的信息。-Xloggc:/data/logs/gc.log
:指定垃圾收集日志文件路径为/data/logs/gc.log
。-XX:+HeapDumpOnOutOfMemoryError
:在发生内存溢出错误时生成堆转储文件。-XX:HeapDumpPath=/data/logs/heapdump.hprof
:指定堆转储文件的路径为/data/logs/heapdump.hprof
。