You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java8+Tomcat8 Spring应用上传文件触发SIGBUS错误求助

文件上传时触发SIGBUS错误的排查与解决

问题概述

基于Java 8(8u201)和Tomcat 8的Spring应用,原本运行正常,近期在文件上传流程中触发SIGBUS崩溃,错误发生在Files.copy执行阶段(此前System.out.println可正常输出目标路径),重构代码后问题仍存在。

错误日志片段

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGBUS (0x7) at pc=0x00007f5c1f9dc200, pid=367, tid=0x00007f5ba8c4a640
#
# JRE version: Java(TM) SE Runtime Environment (8.0_201-b09) (build 1.8.0_201-b09)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.201-b09 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# V  [libjvm.so+0x7dc200]
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
---------------  T H R E A D  ---------------

Current thread (0x00007f5c187fc000):  JavaThread "http-nio-8443-exec-9" daemon [_thread_in_vm, id=417, stack(0x00007f5ba8b4b000,0x00007f5ba8c4b000)]

siginfo: si_signo: 7 (SIGBUS), si_code: 2 (BUS_ADRERR), si_addr: 0x00007f5b662127aa

相关代码片段

Path copyLocation = Paths.get(uploadDir + File.separator + StringUtils.cleanPath(fileName)); 
System.out.println("copyLocation of Files:" + copyLocation); 
Files.copy(file.getInputStream(), copyLocation, StandardCopyOption.REPLACE_EXISTING);

原因分析

SIGBUS(BUS_ADRERR)表示进程尝试访问的内存地址有效,但未映射到物理内存,结合场景可能的触发点:

  • 磁盘IO异常:上传目标目录或Tomcat临时目录磁盘满、权限不足,导致文件写入时底层内存映射失败
  • JVM NIO bug:Java 8u201存在NIO相关的已知bug,在处理文件流复制时可能触发底层JVM崩溃
  • 临时文件异常:Tomcat处理上传时生成的临时文件被意外清理(比如系统定时清理临时目录),导致file.getInputStream()指向的文件失效,后续复制操作触发内存错误

解决方案

1. 检查磁盘状态

  • 检查上传目标目录和Tomcat临时目录(默认CATALINA_BASE/temp)的剩余磁盘空间,确保有足够存储容量
  • 验证目录的读写权限,确保Tomcat运行用户对两个目录拥有完整的读写权限

2. 调整Tomcat上传配置

  • 在conf/web.xml中配置文件上传参数,避免临时文件处理异常:
    <multipart-config>
        <max-file-size>10485760</max-file-size> <!-- 10MB -->
        <max-request-size>20971520</max-request-size> <!-- 20MB -->
        <file-size-threshold>4096</file-size-threshold> <!-- 4KB -->
    </multipart-config>
    
  • 启动Tomcat时显式指定安全的临时目录,避免系统临时目录被清理:
    # 添加到Tomcat启动脚本
    JAVA_OPTS="$JAVA_OPTS -Djava.io.tmpdir=/path/to/your/tomcat-temp"
    

3. 升级JVM版本

Java 8u201存在多个NIO相关的已知缺陷,建议升级到Java 8u301及以上的稳定补丁版本,修复底层bug。

4. 替换文件复制实现

绕开Files.copy的NIO内存映射逻辑,改用传统的流复制方式:

Path copyLocation = Paths.get(uploadDir + File.separator + StringUtils.cleanPath(fileName)); 
System.out.println("copyLocation of Files:" + copyLocation); 

// 替换原Files.copy代码
try (InputStream inputStream = file.getInputStream();
     FileOutputStream outputStream = new FileOutputStream(copyLocation.toFile())) {
    byte[] buffer = new byte[8192];
    int bytesRead;
    while ((bytesRead = inputStream.read(buffer)) != -1) {
        outputStream.write(buffer, 0, bytesRead);
    }
} catch (IOException e) {
    // 加入业务异常处理逻辑
    log.error("文件复制失败", e);
    throw new RuntimeException("文件上传失败", e);
}

5. 启用Core Dump深入排查

执行以下命令后重启应用,下次崩溃时生成core dump文件,结合gdb和jstack工具进一步定位底层问题:

ulimit -c unlimited

内容的提问来源于stack exchange,提问作者Bigyan Kharel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 23:10:27