gpt4 book ai didi

java - Groovy 更新导致 PermGen 中出现大量死掉的 GroovyClassLoaders

转载 作者:行者123 更新时间:2023-11-30 06:16:21 25 4
gpt4 key购买 nike

我有一个 Java 7 项目,每 n 分钟由 n 个进程运行脚本。以下是运行脚本的代码示例。

ScheduledFuture scheduledFuture = scheduledService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
try (GroovyClassLoader cl = new GroovyClassLoader()) {
// Load up reusable script modules in the class loader
Class scriptClass = cl.parseClass(scriptSource);
Foo script = optimizationClass.newInstance();

// Tell Groovy that we don't need class meta info
GroovySystem.getMetaClassRegistry().removeMetaClass(scriptClass);
script.run();
cl.clearCache();
} catch (IOException e) {
LOGGER.error("Failed to cleanup Groovy class loader, this will cause a memory leak", e);
}
}
}, 0, scheduledRun, TimeUnit.SECONDS);

scheduledFuture.get();

出于某种原因,Groovy 2.1.7 在 Perm Gen 中没有内存泄漏。当升级到 Groovy 2.3.8 或 Groovy 2.2.0 时,Perm Gen 不断充满死的 Groovy 类加载器。

0x000000071ada2cd0 33 488160 0x000000071b2493c8 dead groovy/lang/GroovyClassLoader$InnerLoader@0x00000007c7b70ef8 0x00000007265883b8 33 488160 0x0000000725837270 dead groovy/lang/GroovyClassLoader$InnerLoader@0x00000007c7b70ef8 0x00000007157b5da0 26 370736 0x000000072326f468 live org/codehaus/groovy/runtime/callsite/CallSiteClassLoader@0x00000007c831d388 0x000000071ada1fb0 32 423944 0x000000071af03a98 dead groovy/lang/GroovyClassLoader$InnerLoader@0x00000007c7b70ef8 0x0000000719d605b0 32 456520 0x000000071af04798 dead groovy/lang/GroovyClassLoader$InnerLoader@0x00000007c7b70ef8 0x0000000725b82500 0 0 0x000000072326f468 dead groovy/lang/GroovyClassLoader@0x00000007c74c33e8 0x00000007263eef80 34 532448 0x0000000726d5c678 dead groovy/lang/GroovyClassLoader$InnerLoader@0x00000007c7b70ef8 0x000000072687b3c8 33 485288 0x0000000726c36340 dead groovy/lang/GroovyClassLoader$InnerLoader@0x00000007c7b70ef8 0x0000000725d56db0 33 485288 0x000000072607bcc0 dead groovy/lang/GroovyClassLoader$InnerLoader@0x00000007c7b70ef8

我一直等到 Full GC 发生,但似乎 Groovy 2.2 之后的任何版本都会导致 Perm Gen 填满。我检查了我所使用的版本与更新版本之间的发行说明,但我没有注意到任何会触发此问题的更改。

我在这里检查了类似的问题并尝试了一些建议,但没有成功。关于原因有什么想法吗?

更新:
从 2.1.7 到 2.2.0,我在 GroovyClassLoader 上的 GrepCode 上做了一个 Diff,没有任何变化。我还在应用程序运行时获取了一个堆转储文件,并且没有任何指向 GC 根目录的路径以获取强引用。

问题似乎就在这里:

Class scriptClass = cl.parseClass(scriptSource);
Foo script = scriptClass.newInstance();

当我不编译脚本时,我在 Perm Gen 中得到了 0 个 Groovy 类加载器。当我编译脚本但不运行它时,我得到了死的 Groovy 类加载器。

更新:
找到导致泄漏的代码。

Foo script = scriptClass.newInstance();

不确定如何解决这个问题,因为我需要创建一个新实例才能运行脚本。

最佳答案

我在使用 groovy 脚本编译和运行时遇到了同样的问题。我终于用这些方式解决了:1. 如果你使用 7 以下的 java 版本,你可以使用下面的代码在编译后清理你的类

 public static void clearAllClassInfo(Class<?> type) throws Exception {
Field globalClassValue = ClassInfo.class.getDeclaredField("globalClassValue");
globalClassValue.setAccessible(true);
GroovyClassValue classValueBean = (GroovyClassValue) globalClassValue.get(null);
classValueBean.remove(type);
}

2。否则你很幸运,因为你只需要在 SystemProperties 中添加一个属性

-Dgroovy.use.classvalue=true

关于java - Groovy 更新导致 PermGen 中出现大量死掉的 GroovyClassLoaders,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27451058/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com