Apache POI生成Excel时K8s环境JVM崩溃问题求助
问题描述
我开发的Web应用使用Apache POI实现数据写入Excel并提供下载功能,在Linux虚拟机上运行正常,但部署到K8s环境后,每次触发下载请求都会导致JVM崩溃。
关键崩溃信息
JVM崩溃日志核心片段
# A fatal error has been detected by the Java Runtime Environment: # # SIGSEGV (0xb) at pc=0x00007f808e739294, pid=1, tid=0x00007f7fe52a4700 # # JRE version: Java(TM) SE Runtime Environment (8.0_241-b07) (build 1.8.0_241-b07) # Java VM: Java HotSpot(TM) 64-Bit Server VM (25.241-b07 mixed mode linux-amd64 compressed oops) # Problematic frame: # C [libc.so.6+0x10b294] __clock_gettime+0x24 # # The crash happened outside the Java Virtual Machine in native code.
Java调用栈关键路径
org.apache.poi.ss.util.SheetUtil.getDefaultCharWidth(Workbook) org.apache.poi.xssf.streaming.AutoSizeColumnTracker.<init>(Sheet) org.apache.poi.xssf.streaming.SXSSFSheet.<init>(SXSSFWorkbook, XSSFSheet)
运行环境
操作系统:Alpine Linux v3.13
libc版本:glibc 2.30
解决方案
从崩溃路径看,问题是POI自动计算列宽时触发了Java字体管理的本地代码崩溃,结合Alpine环境的特性,可按以下方案解决:
禁用自动列宽计算:
替换POI自动计算列宽的逻辑,手动设置固定列宽,避免触发字体相关的本地调用:// 示例:设置第0列宽度为15个字符(POI中列宽单位为1/256字符宽度) sheet.setColumnWidth(0, 256 * 15);启用Java无头模式:
在JVM启动参数中添加-Djava.awt.headless=true,让Java在无图形环境下运行,跳过X11字体管理器的初始化,避免触发崩溃的本地代码路径。更换基础镜像:
Alpine Linux默认使用musl libc,与Oracle JDK兼容性较差,换成基于Debian/Ubuntu的OpenJDK镜像(如openjdk:8-jdk-slim),这类镜像使用glibc,能更好适配Oracle JDK的本地调用。在Alpine镜像中补充依赖:
如果必须使用Alpine,安装字体配置工具和基础字体,确保Java能正常加载字体:apk add --no-cache fontconfig ttf-dejavu同时在JVM参数中指定字体路径:
-Dsun.font.fontpath=/usr/share/fonts/TTF
内容的提问来源于stack exchange,提问作者ayumi
相关产品推荐
相关产品推荐

