Hibernate SqlFragment内存泄漏?

jul*_*dev 5 java spring garbage-collection hibernate

我在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>
Run Code Online (Sandbox Code Playgroud)

这里是我的jvm选项:

JAVA_OPTS="-Xms1g -Xmx1g -XX:MaxPermSize=512m -XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled -XX:CMSInitiatingOccupancyFraction=30"
Run Code Online (Sandbox Code Playgroud)

Ale*_*leš 0

直方图是一个好的开始,现在您知道要寻找什么了。

接下来,收集堆转储并查看SqlFragment实例来自何处。使用 进行分析Eclipse MAT- 这可能会向您显示该代码是“问题嫌疑人”,您可以从那里开始 - 分析它的输入/输出对这些类的引用。还要检查终结器。

此外,jProfiler 快照可以告诉您谁在分配SqlFragment- 这将向您显示谁负责该分配 - 无论是您的代码还是休眠。

此外,我还建议在 OOM 异常之前收集线程转储,以便您了解系统中发生的情况。