2. What Is a Resource Leak?
And Why You Should Care About Them
3. What Is a Resource Leak?
A resource leak is an erroneous pattern of
resource consumption where a program does
not release resources it has acquired. Typical
resource leaks include memory
leaks and handle leaks.
4. Why You Should Care
Consequences to users:
• Poor performance
• Poor stability or reliability
• Denial of service
Consequences to developers:
• Time consuming to find, even with a debugger
• Can reduce reliability of the testing suite by interrupting
test runs
5. Question:
Java is a modern language with a garbage
collector to take care of resource
management. Doesn’t that mean that I don’t
need to worry about resource leaks?
6. Answer:
No!
The garbage collector (GC) can help ensure
unused objects on the heap are reclaimed
when they are no longer used. But:
• It can't guarantee that you will have the resources you
need, when you need them
• Reference subtleties can “trick” the GC into leaving
unexpected objects on the heap
• Many objects, such as database connections and file
handles, are managed by the operating system - not Java
7. Consider This Code Snippet*
Note:
• It tries to handle exceptions while shutting down the database
• It creates Connection and Statement objects on lines 43 and 44
• This method is associated with a task and may run repeatedly
* From an open source project
8. Best Case:
1. L43: “con” allocated,
connected to db.
2. L44: statement created,
“SHUTDOWN” executed
3. Assuming no exceptions occur, the method exits
4. Eventually, the GC detects that the handles are no longer
used and schedule calls to their finalizers
5. In a later pass, the finalizers will be called, releasing the
underlying handles
6. All is good
9. Reality:
1. L43: “con” allocated,
connected to db.
2. L44: statement created,
“SHUTDOWN” executed
3. Assuming no exceptions occur, the method exits
4. The application continues to work with the database in
other methods
5. Eventually, other methods are unable to get new
statement handles and fail
6. The GC never gets to detect that the handles are no longer
used, or scheduled calls to their finalizers never get run
10. To Avoid the Problem:
Explicitly close the handles
Replace lines 43 and 44 with something like the following
code:
Connection con = null;
Statement stmt = null;
try {
con = DriverManager.getConnection(<url>);
stmt = con.createStatement();
stmt.execute("SHUTDOWN");
// Perhaps some catch blocks for SQLException, etc.
} finally {
// if you’re paranoid, put these in a separate try/catch for SQLException
if (stmt != null) { stmt.close(); }
if (con != null) { con.close(); }
}
Note that Java 7 has a simplified “try-with-resources”
statement.
11. In Short…
1. Remain vigilant about resource usage
• Explicitly close resources when you are done with them
• Be careful to handle exceptional cases, too!
2. Use tools to identify cases that you miss
• Static analysis (often available in IDE, too!)
• Dynamic analysis
3. Enjoy the extra time you’ve freed up