了解GroovyGrails类加载器泄漏

了解GroovyGrails类加载器泄漏,第1张

了解Groovy / Grails类加载器泄漏

Groovy是一种动态语言,每个方法调用都是动态调度的。以优化Groovy中创建一个

metaClass
为每个
java.lang.Class
metaClassRegistry
。这些
metaClass
实例是按需创建的,并使用弱引用进行存储。

之所以看到很多,

org.prehaus.groovy.runtime.metaclass.metaMethodIndex.Entry
是因为Groovy将类和方法的映射存储在内存中,以便可以在运行时快速调度它们。取决于应用程序的大小,这可能是因为您已经发现了数千个类,因为每个类可以具有数十个有时数百个方法。

但是,在Groovy和Grails中没有“内存泄漏”,您看到的是正常行为。您的应用程序内存不足,可能是因为尚未为其分配足够的内存,从而导致

metaClass
实例被垃圾回收。现在假设您有一个循环:

for(str in strings) {   println str.toUpperCase()}

在这种情况下,我们正在

String
类上调用一个方法。如果内存不足,则将发生以下情况:对于循环的每次迭代,
metaClass
将对其进行垃圾回收,然后再次为下一次迭代重新创建。如您所见,这会大大降低应用程序的运行速度,并导致CPU被固定。此状态通常称为“元类搅动”,是您的应用程序堆内存不足的标志。

如果Groovy中 没有 垃圾收集这些metaClass的情况下,那么是的,这将意味着有在Groovy内存泄漏,但事实证明 这是
垃圾收集这些类是一个迹象,一切都很好,只是,你还没有分配到足够的事实首先堆内存。这并不是说在应用程序的另一部分中可能存在内存泄漏,这正在耗尽所有可用的内存,并且不足以使Groovy正常运行。

至于您提到的其他答案, 除非 您在运行时动态解析类, 否则
添加类卸载和PermGen调整实际上不会解决内存问题。JVM使用PermGen空间存储动态创建的类。Groovy允许您在运行时使用

GroovyClassLoader.parseClass
或编译类
GroovyShell.evaluate
。如果您要连续解析类,那么可以添加类卸载标志会有所帮助。

但是,典型的Grails应用程序 不会 在运行时动态编译类,因此调整PermGen和类卸载设置实际上并不会实现任何目的。

您应该使用-Xmx标志验证是否分配了足够的堆内存,如果没有分配更多的堆内存,则应使用-Xmx标志。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5489232.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-12
下一篇 2022-12-12

发表评论

登录后才能评论

评论列表(0条)

保存