What is a memory leak

What is a memory leak

In computers, a memory leak refers to software programs which consume memory but fail to release it. This will usually cause memory overflow, slowing down the entire system and sometimes crashing the software. Memory leaks are a common issue when writing programs in Java language. Java garbage collector will destroy the ghost objects which do not have any references in the memory, however if you leave a reference open to objects, the garbage collector will fail to remove that object and the memory will be kept in use.

How to detect memory leak in Java

Fortunately, there are some tools coming with Java which helps us easily identify a memory leak in our software and resolve it. These tools includes JMAP and JHAT. First step would be to identify how much memory your Java application is consuming normally and then watch the memory use for any suspicious behaviour. In Linux you can run “top” command to monitor memory usage for your applications:

java-memory-usage

In this example, the software is using 471MB memory which I would suspect something is going wrong as this amount keep growing by time. The next step would be to export the heap from memory into a binary file for analysis. This way we can detect which section in our file is causing this memory leak. To do so, we will need jmap command and the process id which we can get it from the “top” command ( in this example 4779 ).

jmap -heap:format=b 4779

After running this command, we have the heap.bin file which then can be used with jhat (Java Heap Analysis Tool) command, You can increase the maximum memory usage depending the heap size to avoid memory overflow error:

jhat -J-Xmx1000m heap.bin

After running this command, you will now have access to the JHAT web interface analysis using the default port number 7000 by accessing the following URL:

http://127.0.0.1:7000/

In this section, you will have a summary of all classes and instances in the memory, Scroll down and click on the Heap Histogram link, then click on the Instance count to find out which objects have most of the instances in the memory:

java-heap-histogram

In this example, the top instances are object, string and integer variables, however one of the items in the list refers to com.mysql.jdbc.JDBC4PreparedStatement class which means that we have left the PreparedStatement object instances open after executing the query. This usually happens if you do not close the ResultSet and PreparedStatement objects in your function.

Solution

The safest way to run queries is to use a finally block in the try/catch statements to close the objects in there in case of any errors which may occur during execution of your query:

public void getOrders( int CustomerId ) throws SQLException {

    PreparedStatement query = null;
    ResultSet rs = null;

    String queryString =
        "select * from orders where customer_id = ?";

    try
    {
        query = con.prepareStatement(queryString);
        query.setInteger ( 1 , customerId );
        rs = query.executeQuery();
    }
    catch (SQLException e )
    {
        System.out.println ( "Error: " + e.getMessage() );
    }
    finally
    {
        if (rs != null)
        {
            rs.close();
        }
        if (query != null)
        {
            query.close();
        }
    }
}

About majid

Software engineer, Web developer and IT graduate. Profile: View My Profile
This entry was posted in Tutorials. Bookmark the permalink.