java – Hibernate SqlFragment内存泄漏?
发布时间:2020-12-14 19:33:09 所属栏目:Java 来源:网络整理
导读:我在Tomcat服务器上部署了一个简单的webapp. webapp是一个REST Web服务,每个Web资源从 MySQL数据库加载数据并返回XML或JSON文档.我使用以下框架堆栈:Jersey(1.14)Spring(3.1)Hibernate(4.1)EHCache(2.5.1). 我用jMeter测试了webapp:我启动了5个线程来请求W
我在Tomcat服务器上部署了一个简单的webapp. webapp是一个REST Web服务,每个Web资源从
MySQL数据库加载数据并返回XML或JSON文档.我使用以下框架堆栈:Jersey(1.14)Spring(3.1)Hibernate(4.1)EHCache(2.5.1).
我用jMeter测试了webapp:我启动了5个线程来请求Web资源.几分钟后,堆已经开始缓慢填充达到99%并最终返回OOM异常.我不知道它是否是内存泄漏但是当我在内存堆中看到大量的org.hibernate.hql.internal.ast.tree.SqlFragment对象时?!! /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> 这里是我的jvm选项: JAVA_OPTS="-Xms1g -Xmx1g -XX:MaxPermSize=512m -XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled -XX:CMSInitiatingOccupancyFraction=30" 解决方法
我将我的jvm从1.6更新21更新到1.6更新38,泄漏似乎已修复.
现在我在压力期间只有17个SQLFragment实例. /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 注意:JDK更新没有解决问题! 我用jmeter测试了所有REST资源,以确定哪个资源泄漏. 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(); 这里是刚刚启动Tomcat后SqlFragment的数量. jmap -histo:live 27472 | grep -i SqlFragment 608: 15 840 org.hibernate.hql.internal.ast.tree.SqlFragment 并且1个http请求完全垃圾后的SqlFragment数量 jmap -histo:live 27472 | grep -i SqlFragment 503: 37 2072 org.hibernate.hql.internal.ast.tree.SqlFragment 为了快速解决这个问题,我将HQL请求重写为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(); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容