Using Try‑with‑Resources for GZIP Compression in Java: Avoiding Resource Leaks
This article explains how to compress large objects with GZIP before storing them in Redis, demonstrates the pitfalls of not closing streams, shows how Java's try‑with‑resources simplifies resource management, and provides best‑practice code examples to prevent hidden IO exceptions.
In the introduction, the author describes a task to compress large JSON objects with GZIP before writing them to a Redis cluster to save memory, and presents an initial implementation that works but forgets to close streams.
The second section points out the hidden risk: failing to close GZIPInputStream or GZIPOutputStream can cause memory leaks, and the fix is simply adding a finally block to close the streams.
The third section introduces Java 7's try‑with‑resources syntax, showing an optimized version of the code where the compiler automatically inserts the necessary finally logic. A compiled class file screenshot illustrates this behavior.
The fourth section discusses the limitations of try‑with‑resources, noting that only classes implementing Closeable (or AutoCloseable ) can be used, and confirms that ByteArrayOutputStream and GZIPOutputStream already implement Closeable .
public class ByteArrayOutputStream extends OutputStream {}
public abstract class OutputStream implements Closeable, Flushable {}
public class GZIPOutputStream extends DeflaterOutputStream {}
public class DeflaterOutputStream extends FilterOutputStream {}
public class FilterOutputStream extends OutputStream {}
public abstract class OutputStream implements Closeable, Flushable {}The fifth section provides a custom class implementing Closeable to demonstrate automatic resource release:
public class ImageStream implements Closeable {
public void work() {
System.out.println("开始工作");
}
@Override
public void close() throws IOException {
System.out.println("自动释放资源");
}
}
public static void main(String[] args) throws IOException {
try (ImageStream is = new ImageStream()) {
is.work();
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
}The output shows the work message followed by the automatic release message.
The sixth section highlights a subtle pitfall: when multiple resources are declared in a single try‑with‑resources statement, if finish() throws an exception, the subsequent out.close() may not execute. The solution is to declare each stream separately.
try (
OutputStream out = new FileOutputStream(createdFile);
GZIPOutputStream gzipOutputStream = new GZIPOutputStream(out);
OutputStreamWriter osw = new OutputStreamWriter(gzipOutputStream);
BufferedWriter bw = new BufferedWriter(osw)
) {
// ...
} catch (Exception ex) {
// ...
}The final section summarizes three take‑aways: developers should respect resource management beyond functional correctness, try‑with‑resources helps reduce boilerplate but is not a silver bullet, and understanding both benefits and hidden risks prevents future bugs.
Java Architect Essentials
Committed to sharing quality articles and tutorials to help Java programmers progress from junior to mid-level to senior architect. We curate high-quality learning resources, interview questions, videos, and projects from across the internet to help you systematically improve your Java architecture skills. Follow and reply '1024' to get Java programming resources. Learn together, grow together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.