I am reviewing some legacy code and noticed many database connections and file streams lack proper closing blocks. Can someone explain what causes memory leaks in Java applications when system resources are left open? Does the JVM eventually clear these up, or will it cause an OutOfMemoryError?
3 answers
When you open system resources like file streams, network sockets, or database connections, the operating system allocates underlying handles to your Java process. If you fail to close these explicitly, the Java objects wrapping them stay referenced by the runtime framework, meaning they cannot be garbage collected. Even if the local variable goes out of scope, the system-level link remains open, draining physical memory and OS file descriptors. Over time, this cumulative resource hoarding will inevitably lead to an OutOfMemoryError and crash the system.
Is there a modern coding standard or automated IDE configuration that can catch these unclosed streams before they ever get merged into the main deployment branch?
We migrated our legacy code to the try-with-resources syntax last year and it instantly eliminated half of our random application crashes.
That is a great move, Brandon. It makes the code cleaner and guarantees that resources close safely even if runtime exceptions occur.
Yes Jeffrey, you should strictly enforce the try-with-resources statement introduced in Java 7 for any class implementing AutoCloseable. Additionally, incorporating static analysis tools like SonarQube into your CI/CD pipeline will automatically flag any unclosed resources during build time.