【问题标题】:Class loader memory leak in a Grails appGrails 应用程序中的类加载器内存泄漏
【发布时间】:2026-01-24 03:30:01
【问题描述】:

我有一个在 tomcat 上运行的 grails 应用程序,它似乎正在泄漏类加载器,并且在运行大约 2 周后它抛出了 OOME。但是,我无法弄清楚问题的根本原因是什么。任何有关如何解决此问题的帮助将不胜感激。

已安装 Grails 插件

app.grails.version=1.3.7
app.name=bm
app.servlet.version=2.4
app.version=0.1
plugins.database-migration=1.0
plugins.executor=0.3
plugins.export=0.9
plugins.google-visualization=0.5
plugins.hibernate=1.3.7
plugins.mail=1.0-SNAPSHOT
plugins.quartz=0.4.2
plugins.spring-security-core=1.2.1
plugins.tomcat=1.3.7

JMAP 输出

 num     #instances         #bytes  class name
----------------------------------------------
1:        140060       18764192  <constMethodKlass>
2:        164561       17114344  org.codehaus.groovy.runtime.metaclass.MetaMethodIndex$Entry
3:        140060       16817936  <methodKlass>
4:         14326       15583816  <constantPoolKlass>
5:        157629       14203608  [C
6:         14326       12833728  <instanceKlassKlass>
7:         71899       10928648  java.lang.reflect.Method
8:         12865        9810400  <constantPoolCacheKlass>
9:        155186        9471320  <symbolKlass>
10:         28791        9364696  [B
11:        164650        7903200  java.util.concurrent.locks.ReentrantLock$NonfairSync
12:        164496        7895808  java.util.concurrent.ConcurrentHashMap$Segment
13:        154748        7427904  java.util.HashMap$Entry
14:        137621        7235504  [Ljava.lang.Object;
15:        178058        7122320  java.lang.String
16:        164496        5876008  [Ljava.util.concurrent.ConcurrentHashMap$HashEntry;
17:         25224        5322656  [Ljava.util.HashMap$Entry;
18:         16359        4774824  [Lorg.codehaus.groovy.util.ComplexKeyHashMap$Entry;
19:          6456        3368704  <methodDataKlass>
20:         69962        3358176  org.codehaus.groovy.util.SingleKeyHashMap$Entry
21:         59890        3353840  java.lang.ref.SoftReference
22:         69222        3322656  java.lang.ref.WeakReference
23:         31530        3026880  java.beans.MethodDescriptor
24:         22579        2890112  java.lang.reflect.Field
25:           897        2824728  [Lorg.codehaus.groovy.runtime.metaclass.MetaMethodIndex$Entry;
26:         15006        2761104  java.lang.Class
27:         45281        2592272  [I
28:         23921        2487784  org.codehaus.groovy.reflection.CachedMethod
29:         46947        1877880  java.util.ArrayList
30:         58290        1865280  org.codehaus.groovy.util.FastArray
31:         21968        1832888  [[I
32:         56895        1792872  [Ljava.lang.Class;
33:            34        1681456  [Lorg.apache.commons.collections.map.AbstractHashedMap$HashEntry;
34:         46489        1661760  [Ljava.lang.String;
35:         10267        1562376  [Ljava.util.concurrent.ConcurrentHashMap$Segment;
36:         12511        1501320  java.lang.reflect.Constructor
37:         30817        1479216  java.util.concurrent.ConcurrentHashMap$HashEntry
38:         17869        1248784  [S
39:         19447        1244608  java.util.HashMap
40:         20885        1169560  groovy.lang.MetaBeanProperty

我想知道执行器插件是否是罪魁祸首,因为并发HashMap 条目的数量很大。我在不同时间使用 jmap 检查了我自己的类的实例数量,它们似乎并没有增加。我该如何解决这个问题,即使你可以为我提供一个“解决”这个问题的方法,它也会很棒。

【问题讨论】:

  • 确保它不是著名的“tomcat permgen space”错误,它是在重新部署应用程序后发生的
  • 不存在“著名的'tomcat permgen space'错误”之类的东西。每一个 permgen oom 都是由于应用程序或其中一个库中的错误造成的。
  • 我已经关闭并重新启动了tomcat以及应用程序,但仍然会发生这种情况。所以我猜这个可以排除。

标签: java grails memory-leaks groovy out-of-memory


【解决方案1】:

可能值得一试Plumbr。它现在也发现了 permgen 泄漏,并且这个功能暂时是免费的。

【讨论】:

    【解决方案2】:

    快速的 Google 搜索提供了以下来源:

    Troubleshooting Grails/Groovy memory leaks?

    http://www.wapolabs.com/2011/12/13/profiling-a-grails-application-with-a-runaway-memory-leak/

    如果你觉得是插件问题,移除插件测试难度有多大?

    【讨论】:

    • 这是一个生产中的应用程序。所以删除插件会有点困难。但我想我可以在本地删除它并尝试一下。