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

Java堆内存不足致线程执行异常:文件仅创建未写入原因探究

堆内存不足导致文件写入异常问题分析

测试场景描述

  1. JVM参数为-Xms10m -Xmx10m时
    程序正常运行,成功创建1000个带有内容的文件,代码如下:
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;

public class Test {
    public static final int COUNT = 1_000;

    public static void main(String[] args) {
        testByThread();
    }

    public static void testByThread() {
        long start = System.currentTimeMillis();
        for (int i = 0; i < COUNT; i++) {
            int finalI = i;
            new Thread(() -> {
                int num = write1("threadTest", finalI);
                System.out.println(num);
            }).start();
        }
        System.out.println("total: " + (System.currentTimeMillis() - start));
    }

    public static int write1(String name, int i) {
        try {
            String content = "This is the content to write into create file";
            String path = "D:" + name + i + ".txt";
            File file = new File(path);

            FileWriter fw = new FileWriter(file.getAbsoluteFile());
            BufferedWriter bw = new BufferedWriter(fw);

            bw.write(content);
            bw.close();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        return i + 1;
    }
}
  1. JVM参数调整为-Xms2m -Xmx2m时
    控制台抛出大量如下异常:
Exception in thread "Thread-253" java.lang.OutOfMemoryError: Java heap space
Exception in thread "Thread-254" java.lang.OutOfMemoryError: Java heap space
...

此时虽成功创建1000个文件,但其中275个文件大小为0KB,无内容写入。

问题解析

为何部分线程仅创建文件未写入内容?

核心原因是堆内存耗尽导致线程在写入逻辑执行阶段抛出OutOfMemoryError,写入流程被直接中断。

write1方法的完整执行异常拆解

逐个阶段看线程执行write1时的情况:

  • 文件创建阶段:new File(path)和new FileWriter(file.getAbsoluteFile())会触发文件创建,这部分操作依赖本地文件系统,几乎不占用堆内存,所以即使堆内存不足,这一步也能完成,空文件因此被创建。
  • 写入准备/执行阶段触发OOM:
    1. 创建BufferedWriter时,它默认会在堆内存中分配8KB左右的缓冲区。如果此时堆内存已经耗尽,这一步会直接抛出OutOfMemoryError,后续的bw.write(content)和bw.close()完全没机会执行。
    2. 就算缓冲区创建成功,执行bw.write(content)时,字符串的处理、缓冲区扩容(如果需要)也会占用堆内存,同样可能触发OOM,导致写入中断。
  • 异常无法被捕获:方法中的catch (Exception e)只能捕获Exception及其子类,而OutOfMemoryError属于Error类,根本不会被这个catch块捕获。线程抛出OOM后直接终止,写入流程彻底中断,文件自然为空。

额外说明

  • 部分线程能正常写入,是因为它们启动较早,在堆内存耗尽前就完成了缓冲区分配、内容写入、资源关闭的全流程。
  • 最终能创建1000个文件,是因为文件创建操作不依赖堆内存,即便线程后续因OOM挂掉,文件已经被成功创建。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 11:53:14