Flink 1.16.0 TaskManager启动失败:JVM内存不足问题求助
Flink TaskManager内存配置启动崩溃的排查与解决
问题现象
- 基于Flink 1.16.0通过Docker Compose部署,将TaskManager的
taskmanager.memory.process.size设为32GB时,容器启动后立即崩溃;调整为29GB及以下时,64GB内存的生产服务器可正常运行。 - 本地16GB内存机器未触发该问题。
报错信息
OpenJDK 64-Bit Server VM warning: INFO: os::commit_memory(0x00000003ab000000, 18605932544, 0) failed; error='Not enough space' (errno=12)
There is insufficient memory for the Java Runtime Environment to continue.Native memory allocation (mmap) failed to map 18605932544 bytes for committing reserved memory.An error report file with more information is saved as:/opt/flink/hs_err_pid1.log
环境信息
- 生产服务器:Red Hat Enterprise Linux Server 7.9,物理内存64GB
- Docker版本:Engine - Community 20.10.17,Compose 2.6.0
- 未禁用jemalloc
- Flink镜像:JobManager用
flink:1.16.0-scala_2.12-java11,TaskManager用flink:1.16.0-scala_2.12
Docker Compose配置
services: jobmanager: image: flink:1.16.0-scala_2.12-java11 ports: - "${FLINK_WEB_PORT}:8081" command: jobmanager environment: - | FLINK_PROPERTIES= jobmanager.rpc.address: jobmanager state.backend: hashmap taskmanager: image: flink:1.16.0-scala_2.12 depends_on: - jobmanager command: taskmanager environment: - | FLINK_PROPERTIES= jobmanager.rpc.address: jobmanager taskmanager.numberOfTaskSlots: 8 taskmanager.memory.process.size: 32gb state.backend: hashmap
排查与解决方法
1. 检查Docker容器内存限制
默认Docker容器无内存上限,但生产环境可能通过/etc/docker/daemon.json设置了默认配额。可执行docker info | grep Memory查看默认限制,或在Compose中为TaskManager显式配置内存预留与上限,预留额外空间给JVM native内存和容器系统开销:
taskmanager: # 保留原有配置 deploy: resources: limits: memory: 34gb reservations: memory: 32gb
2. 拆分Flink内存配置
taskmanager.memory.process.size包含JVM堆、直接内存、元空间、native内存等所有进程内存。拆分配置可避免JVM过度占用native内存,示例如下:
taskmanager.memory.flink.size: 29gb taskmanager.memory.jvm-metaspace.size: 512mb taskmanager.memory.jvm-overhead.min: 1gb taskmanager.memory.jvm-overhead.max: 1.5gb
总进程内存约31GB,既接近32GB需求,又降低内存溢出风险。
3. 检查系统内存与交换分区
执行free -h查看生产服务器剩余内存和交换分区状态:
- 若剩余物理内存不足,先清理其他占用内存的进程;
- 若未启用交换分区或分区过小,建议启用并设置为16GB以上,缓解JVM内存压力。
4. 验证jemalloc兼容性
jemalloc可能与JVM内存分配存在冲突,可在TaskManager环境变量中禁用jemalloc测试:
taskmanager: environment: - | FLINK_PROPERTIES= # 保留原有配置 env.java.opts: -Dorg.apache.flink.kubernetes.memory.disable-jemalloc=true
5. 检查OS cgroup内存限制
RHEL 7.9可能通过cgroup限制容器内存:
- 执行
cat /proc/self/cgroup查看TaskManager容器所属的cgroup路径; - 检查对应cgroup的内存配额:
cat /sys/fs/cgroup/memory/<cgroup-path>/memory.limit_in_bytes,确保配额大于32GB。
内容的提问来源于stack exchange,提问作者Dan
相关产品推荐
相关产品推荐

