You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何向Tomcat上传100MB以上文件?修改配置后遇OutOfMemoryError怎么办

解决Tomcat上传大文件时的java.lang.OutOfMemoryError问题

兄弟,太懂这种改了参数反而炸内存的憋屈了——你调大maxPostSize允许更大的请求,但Tomcat默认会把整个请求体(包括你的大文件)直接加载到JVM内存里,文件一超大,内存直接就顶不住了。下面给你几个靠谱的解决方向:

  • 调整Tomcat的请求体存储策略
    Tomcat有个容易被忽略的参数maxSavePostSize,在server.xmlConnector节点里配置,它决定了当请求体超过多大时,Tomcat会把内容写到临时磁盘文件,而不是死死占着内存。建议设置成maxSavePostSize="-1"(-1表示不限制,所有超过内存缓存阈值的请求体都转存磁盘),搭配你已经修改的参数,完整配置大概是这样:

    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443"
               maxPostSize="104857600" <!-- 这里设成你需要的最大文件大小,比如100MB -->
               maxHttpHeaderSize="81920"
               maxSavePostSize="-1" />
    

    另外要注意Tomcat的临时目录(默认是CATALINA_BASE/temp)要有足够的磁盘空间,不然存临时文件会出别的岔子。

  • 优化JVM内存分配
    如果你的应用本身堆内存分配太小,就算用了磁盘缓存,处理大文件时也可能触发溢出。去catalina.sh(Linux)或catalina.bat(Windows)里调整JVM参数:

    # Linux示例:初始堆2G,最大堆4G,根据服务器配置调整
    export JAVA_OPTS="-Xms2g -Xmx4g"
    # Windows示例
    set JAVA_OPTS="-Xms2g -Xmx4g"
    

    别贪多,堆内存最好不要超过服务器物理内存的70%,避免和系统进程抢资源。

  • 改用分块上传(最彻底的方案)
    把大文件切成小 chunks(比如每个10MB),前端分多次上传,后端接收后再合并。这样每次请求的内存占用都极小,完全不会触发内存溢出,还能支持断点续传,用户体验也更好。
    实现的时候,后端可以用MultipartFile接收每个分块,记录好分块序号和文件唯一标识,所有分块传完后再拼接成完整文件。

  • 检查你的代码处理逻辑
    有时候问题不在Tomcat,而是你自己的代码把整个文件读到内存里了——比如用FileUtils.readFileToByteArray或者把MultipartFile转成byte[]存起来。这种情况要改成流式处理,直接把输入流写到磁盘,别先读进内存:

    // 糟糕的写法:把整个文件加载到内存
    byte[] fileBytes = multipartFile.getBytes();
    Files.write(Paths.get("target/file"), fileBytes);
    
    // 推荐的写法:流式写入,内存占用极低
    try (InputStream in = multipartFile.getInputStream();
         OutputStream out = new FileOutputStream("target/file")) {
        byte[] buffer = new byte[8192];
        int bytesRead;
        while ((bytesRead = in.read(buffer)) != -1) {
            out.write(buffer, 0, bytesRead);
        }
    } catch (IOException e) {
        // 处理异常逻辑
    }
    

按优先级来,先调Tomcat的存储策略,再检查代码,最后考虑分块上传,基本能解决你的问题。

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

火山引擎 最新活动