gpt4 book ai didi

java - Class.forName 导致类加载器移至终身代?

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:14:11 27 4
gpt4 key购买 nike

我已经看到 Class.forName() 导致 tenured generation 被填满。我怀疑 JVM 内部所做的某些事情会将 ClassLoader 对象移动到永久代。例如下面的代码:

public class Test  {
public static void main(String[] args) throws Exception {
for (int i=0 ;i<30000;i++) {
test();
}
}
private static void test() throws Exception {
MyClassLoader cl = new MyClassLoader();
Class.forName("java.lang.String", false, cl);
}
}

public class MyClassLoader extends ClassLoader {}

会输出gc日志:

[GC [DefNew: 512K->64K(576K), 0.0041095 秒] 512K->344K(1984K), 0.0042064 秒]
[GC [DefNew: 576K->64K(576K), 0.0032096 秒] 856K->682K(1984K), 0.0032937 秒]
[GC [DefNew: 575K->63K(576K), 0.0032085 秒] 1194K->1021K(1984K), 0.0033686 秒]
[GC [DefNew: 575K->64K(576K), 0.0025146 秒] 1533K->1359K(1984K), 0.0026305 秒]
[GC [DefNew: 576K->64K(576K), 0.0025942 秒][Tenured: 1634K->166K(1664K), 0.0169541 秒] 1871K->166K(2240K), 0.0197106 秒]
[GC [DefNew: 512K->64K(576K), 0.0019209 秒] 678K->505K(1984K), 0.0020053 秒]
[GC [DefNew: 576K->63K(576K), 0.0022846 秒] 1017K->844K(1984K), 0.0024271 秒]
[GC [DefNew: 575K->63K(576K), 0.0023358 秒] 1356K->1182K(1984K), 0.0024235 秒]
[GC [DefNew: 575K->64K(576K), 0.0025660 秒][Tenured: 1457K->166K(1536K), 0.0136841 秒] 1694K->166K(2112K), 0.0164004 秒]

如果将 Class.forName 更改为 loadClass:

private static void test() throws Exception {
MyClassLoader cl = new MyClassLoader();
cl.loadClass("java.lang.String");
//Class.forName("java.lang.String", false, cl);
}

然后 gc 输出将是:

[GC [DefNew: 512K->63K(576K), 0.0028769 秒] 512K->138K(1984K), 0.0029627 秒]
[GC [DefNew: 575K->0K(576K), 0.0009856 秒] 650K->138K(1984K), 0.0010711 秒]
[GC [DefNew: 512K->0K(576K), 0.0006255 秒] 650K->138K(1984K), 0.0007062 秒]
[GC [DefNew: 512K->0K(576K), 0.0002065 秒] 650K->138K(1984K), 0.0002861 秒]
[GC [DefNew: 512K->0K(576K), 0.0001936 秒] 650K->138K(1984K), 0.0002674 秒]
[GC [DefNew: 512K->0K(576K), 0.0002045 秒] 650K->138K(1984K), 0.0002796 秒]
[GC [DefNew: 512K->0K(576K), 0.0001704 秒] 650K->138K(1984K), 0.0002481 秒]
[GC [DefNew: 512K->0K(576K), 0.0002229 秒] 650K->138K(1984K), 0.0003118 秒]

转载于sun jdk1.5和1.6。这里的 jvm(类加载和 gc)内部发生了什么?

谢谢。

最佳答案

您的样本太小,无法真正显示 GC 行为差异的明确原因。首先,您的 MyClassLoader 不应实际加载 java.lang.String 类,因为它已经存在于引导类加载器中。您的 ClassLoader 对象(和 Class 对象本身)应该一直移动到 PermGen 空间,因此您对它们位于永久代的猜测有点可疑。

基本上,您的问题“这里的 JVM 内部发生了什么”太笼统了——仅仅阅读 GC 日志输出并不能真正告诉您太多,因为即使代码中看似微不足道的差异也可能导致截然不同的 GC 模式,尤其是在小测试代码。

关于java - Class.forName 导致类加载器移至终身代?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9450473/

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