Java – hibernate sqlfragment memory leak?

I deployed a simple webapp on the Tomcat server Webapp is a rest web service. Each web resource loads data from MySQL database and returns XML or JSON documents I use the following framework stack: Jersey (1.14) spring (3.1) hibernate (4.1) ehcache (2.5.1)

I tested webapp with JMeter: I started five threads to request web resources After a few minutes, the heap has started to slowly fill up to 99% and finally returned an oom exception I don't know if it's a memory leak, but when I see a lot of org. Org in the memory heap hibernate. hql. internal. ast. tree. Sqlfragment object?!!

/usr/java/jdk/bin/jmap -histo:live 17047 > /tmp/histo.txt

 num     #instances         #bytes  class name
----------------------------------------------
   1:        720143       69133728  org.hibernate.hql.internal.ast.tree.sqlFragment
   2:        510537       63559320  [C
   3:        360221       34581216  org.hibernate.hql.internal.ast.tree.BinaryLogicOperatorNode
   4:        704652       33823296  java.util.HashMap$Entry
   5:        360223       31699624  org.hibernate.hql.internal.ast.tree.sqlNode
   6:        697354       27894160  java.lang.String
   7:        370975       26710200  org.hibernate.hql.internal.ast.tree.Node
   8:        171241       25623320  <constMethodKlass>
   9:        208125       24948176  [Ljava.lang.Object;
  10:        171241       20568632  <methodKlass>
  11:         16012       17827384  <constantPoolKlass>
  12:        383070       16623136  [I
  13:         34829       15170176  [Ljava.util.HashMap$Entry;
  14:        226869       12885896  <symbolKlass>
  15:         16012       12590168  <instanceKlassKlass>

Here are my JVM options:

JAVA_OPTS="-Xms1g -Xmx1g -XX:MaxPermSize=512m -XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled -XX:CMSInitiatingOccupancyFraction=30"

Solution

I updated my JVM from 1.6 update 21 to 1.6 update 38, and the leak seems to have been fixed

/usr/java/jdk/bin/jmap -histo:live 5612 | grep org.hibernate.hql.internal.ast.tree.sqlFragment
 912:            17            952  org.hibernate.hql.internal.ast.tree.sqlFragment
/usr/java/jdk/bin/jmap -histo:live 5612 | grep org.hibernate.hql.internal.ast.tree.sqlFragment
 910:            17            952  org.hibernate.hql.internal.ast.tree.sqlFragment
/usr/java/jdk/bin/jmap -histo:live 5612 | grep org.hibernate.hql.internal.ast.tree.sqlFragment
 980:            17            952  org.hibernate.hql.internal.ast.tree.sqlFragment

Note: JDK update does not solve the problem!

I tested all rest resources with JMeter to determine which resource was leaking I found a resource, and now I can use JMeter to fill all the memory heap in less than 30 seconds I found HQL queries that create a large number of sqlfragments:

String q = "select p from PhysicalItem p where p.product.id=:itemid and p.fileType in (:filetypes) order by p.id desc";
return sessionFactory.getCurrentSession().createQuery(q).setParameter("itemid",logicalItemID).setParameterList("filetypes",fileTypes).list();

Here is the number of sqlfragments just after starting Tomcat

jmap -histo:live 27472 | grep -i sqlFragment
 608:            15            840  org.hibernate.hql.internal.ast.tree.sqlFragment

And the number of sqlfragments after one HTTP request is completely garbage

jmap -histo:live 27472 | grep -i sqlFragment
 503:            37           2072  org.hibernate.hql.internal.ast.tree.sqlFragment

To quickly solve this problem, I rewrite the HQL request as SQL:

String sql = "select p.* from physical_item p where p.id_logical = :itemid and p.file_type in (:filetypes) order by p.id desc";
            List<String> names = new ArrayList<String>();
            for (FileType fileType : fileTypes) {
                names.add(fileType.getName());
            }
            return sessionFactory.getCurrentSession()
                                .createsqlQuery(sql)
                                .addEntity(PhysicalItem.class)
                                .setParameter("itemid",logicalItemID)
                                .setParameterList("filetypes",names)
                                .list();
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>