The Java automatic garbage collection process typically operates as a low-priority thread that
constantly searches memory for unreachable objects, objects not referenced by any other object
reachable by a live thread. Different JVMs use different algorithms to determine how to collect garbage
most efficiently.
In the JVM, memory is allocated in two regions:
• Stack: Where local variables (declared in methods and constructors) are allocated. Local
variables are allocated when a method is invoked and de-allocated when the method is exited.
• Heap: Where all objects created with the new keyword are allocated. Since local variables are
few in number, only primitive types and references, usually the stack will not overflow, except
in cases of unusually deep or infinite recursion. The JVM throws a Java out-of-memory error if
it is not able to get more memory in the heap to allocate more Java objects. The JVM cannot
allocate more objects if the heap is full of live objects and unable to expand further.
First, I executed the application with the Statement and ResultSet objects closed. Subsequently,
I executed the application by not closing the Statement and ResultSet objects. I did a query
operation 50 times and observed the memory usage pattern.
Scenario 1:
The database table contains 100 rows and 10 columns. ResultSet and Statement objects are
closed. The database connection is made using a connection pool. The memory usage results of this
scenario are shown in Figure 1.
Figure 1. When queried once, the heap memory usage increases by 166.308 KB. Click on
thumbnail to view full-sized image.
Figure 1 is a heap usage chart provided by JProbe. It gives a runtime summary of the heap memory in
use over time as the Java EE application runs. The green area indicates the heap usage. The vertical line
indicates a heap usage checkpoint has been set at that time. After setting the checkpoint, the query
occurs and the heap memory usage shoots up as objects are created. Once the operation completes, the
objects no longer referenced will be garbage collected by the JVM, so the memory usage decreases.
Ideally at this time, all new objects should be released and garbage collected, and the heap usage
should return to the value before the checkpoint was set. In this case, some new objects continue to
occupy memory space, reflecting an increase in heap usage by 166.308 KB.
When queried 10 times, the heap memory usage increases by 175.512 KB, as illustrated in Figure 2.
Figure 4. Results from one query. Click on thumbnail to view full-sized image.
When queried 10 times, the heap memory usage increases by 217.016 KB.