Backend Development 6 min read

Resolving Java OOM Caused by Large File Download: GC Log Analysis and Streaming Solutions

The article describes a production OOM incident caused by downloading a 2.4 GB file, walks through GC log and heap‑dump analysis using MAT, identifies the problematic use of FileUtils.readFileToByteArray, and presents streaming and external storage solutions to prevent memory exhaustion.

Selected Java Interview Questions
Selected Java Interview Questions
Selected Java Interview Questions
Resolving Java OOM Caused by Large File Download: GC Log Analysis and Streaming Solutions

Last week a production environment experienced an Out‑Of‑Memory (OOM) error; investigation revealed that a large file download was the root cause, and the article shares a clear troubleshooting workflow suitable for beginners.

Incident Occurrence

On a Friday afternoon the operations team reported that the backend system became sluggish after 14:00: pages loaded but data submission stalled, prompting suspicion of a bug in the system.

Handling Process

Isolate one server for on‑site analysis while restarting the others to keep the service available.

Download GC logs and obtain a heap dump for further analysis.

GC Log Analysis

The JVM was started with the following memory parameters: -Xmx4096m -Xms4096m -Xmn2560m .

Log inspection shows a Full GC occurring every 40 seconds, lasting about 200 ms. After collection the old generation only uses ~15 MB, but the young generation still holds about 2 GB, indicating that the young generation is filling up.

The hypothesis is that objects from the young generation are trying to promote to the old generation but cannot fit, triggering Full GC.

Heap Dump Analysis with MAT

Using Eclipse MAT, the total memory usage exceeds 2 GB. The histogram reveals that the largest consumers are byte[] objects.

Further inspection shows that these byte[] arrays are referenced by ResponseEntity instances.

Code Review

1) Locate the only code related to ResponseEntity .

2) The code uses FileUtils.readFileToByteArray(file) , which reads the entire file into memory before writing it to the response stream.

3) The downloaded file was a 2.4 GB binary, causing the JVM to run out of heap space and trigger Full GC.

Solutions

Use FileSystemResource

@GetMapping("/down")
public ResponseEntity download(@RequestParam("uri") String uri) throws IOException {
    File file = new File(uri);
    if (!file.isFile()) {
        throw new ServiceException("文件不存在");
    }
    String filename = FilenameUtils.getName(uri);
    HttpHeaders headers = new HttpHeaders();
    headers.add("Content‑Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
    HttpStatus status = HttpStatus.OK;
    return new ResponseEntity<>(new FileSystemResource(file), headers, status);
}

Stream with Buffered I/O

@GetMapping("/down")
public void download(@RequestParam("uri") String uri, HttpServletResponse response) throws IOException {
    File file = new File(uri);
    if (!file.isFile()) {
        throw new ServiceException("文件不存在");
    }
    String filename = FilenameUtils.getName(uri);
    response.setHeader("Content‑Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
    try (FileInputStream fis = new FileInputStream(file);
         BufferedInputStream bis = new BufferedInputStream(fis);
         BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream())) {
        FileCopyUtils.copy(bis, bos);
    } finally {
        // try‑with‑resources handles closing
    }
}

Store the File Externally

Upload the file to an object storage service such as OSS or Qiniu Cloud and let clients download directly, bypassing the application server.

These approaches eliminate the need to load the entire file into JVM memory, thereby preventing OOM and improving system stability.

backendJavaperformanceFileDownloadGCOutOfMemory
Selected Java Interview Questions
Written by

Selected Java Interview Questions

A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.