After some investigation, I have found that the program brings out all the data in one session. Hibernate is holding all the objects in its session until session is closed. As a result, the GC can't clear any previous chunk of object from memory.
Since the we are reading the data for readonly purpose, we set the CacheMode.IGNORE on the Query object. It prevents Hibernate to hold the reference of the objects in it's session.
Here is snippet of the code.
Query qry = session.createQuery(query).setCacheMode(CacheMode.IGNORE);