JVM如何处理动态类

Hun*_*hao 2 java jvm bytecode

类定义存储在方法区域中,如Java虚拟机规范所述(Java®虚拟机规范Java SE 7版):

方法区域是在虚拟机启动时创建的.虽然方法区域在逻辑上是堆的一部分,但是简单的实现可能选择不垃圾收集或压缩它.

我们知道,像ASM,cglib,javassist,Hibernate和Spring框架这样的字节码工具正在使用它们.对于公共类文件,JVM加载并解析和初始化并最终使用它,我对JVM如何动态处理字节码工具生成的类感到困惑.我的问题是:

  1. 如果JVM加载,则将动态类解析并初始化为公共类文件?

  2. 它们也存储在方法区域中吗?

  3. JVM如何卸载和清理动态类定义以防止自身发生OutOfMemoryError?

Pet*_*rey 7

所有类都在运行时加载,可能编译为本机代码.因此,在程序启动后生成的类没有什么特别之处.

如果JVM加载,则将动态类解析并初始化为公共类文件?

它加载的方式与程序启动时存在的类相同.

它们也存储在方法区域中吗?

它们以相同的方式存储,实际上很难判断一个类是否是动态的.

JVM如何卸载和清理动态类定义以防止自身发生OutOfMemoryError?

JVM可以卸载它们所在的ClassLoader时卸载类.无论类是否动态,都是如此.

JVM如何知道以不同于"普通"类的方式处理动态类?

有一个特殊的动态类的例子.这些是在运行时生成的lambda类.使它们与众不同的是它们不受类加载器的约束,它们甚至没有正常的类名.当该类的所有实例都未使用时,它们将被卸载.

InnerClassLambdaMetafactory

UNSAFE.defineAnonymousClass(targetClass, classBytes, null);
Run Code Online (Sandbox Code Playgroud)

该类没有附加类名(也不是ClassLoader)

  • "在Java 8中,元空间不会产生OutOfMemoryError"它不是吗?什么是`java.lang.OutOfMemoryError:元数据空间`呢? (2认同)