由类加载器子系统创建的类对象存储在哪里?

时间:2018-10-05 04:50:30

标签: java jvm stack heap heap-memory

我想Java的较新版本将方法区域和堆区域合并为一个堆区域。但这是关于旧版本的。

但是jvm loading 的定义表示为“查找.class文件并创建Class对象的过程”

这些是我的疑问:

  1. 当我们运行.class文件时,它是否首先按原样存储在方法区域中的内存位?完整的.class文件是否只是转换为存储位?还是仅仅是元数据?方法区域中此“类数据” 的内存分配模式到底是什么?
  2. Classloader 类是否使用 Class 类的方法来获取最终存储在方法区域中的该元数据?
  3. 这些Class对象是否与我们使用new创建的对象相同? 我已经看过文档了,但仍然找不到 在哪一步中创建Class对象。 .class文件信息是否转换为元数据并保存为方法区域中的Class对象?

我已经看过文档了。我只需要简单地解释什么是“已加载”?方法区域是否具有具有此元数据的Class对象?还是只是整个.class文件的一点点信息?

编辑:我也知道通过“编写/运行代码”本身意味着整个文件在RAM上都是位格式。我想知道RAM上的这个特殊方法区域是否只是此副本或其完全不同。

2 个答案:

答案 0 :(得分:0)

要全面了解其工作原理,您需要阅读Java虚拟机规范的第5章。简介指出,

Java虚拟机动态加载,链接和初始化类和接口。加载是查找具有特定名称的类或接口类型的二进制表示并从该二进制表示创建类或接口的过程链接是获取类或接口并将其组合到Java虚拟机的运行时状态以便可以执行的过程。类或接口的初始化包括执行类或接口的初始化方法

要回答具体问题:

  1. 该类文件不是按原样加载到方法区域中,而是作为特定于实现的实现(即JVMS并未强制要求)加载该类的内部表示。类(数组类除外)由类加载器加载。类加载器为给定的类创建Class对象的实例(即元数据)。 JVM处理堆中为此对象分配的空间。
  2. 不。类加载器负责创建Class对象,因此不使用该对象的方法。
  3. 是的,Class对象的形式与任何其他Java对象相同。 Class类继承自Object,您可以像调用其他对象一样调用equals,hachCode等方法。

答案 1 :(得分:0)

ClassLoader仅负责查找和读取类文件,并且可以选择将ProtectionDomain与代码位置相关联,以支持安全措施。

然后它将字节传递到每个类加载器都继承的defineClass方法之一。这些方法将类文件字节(以数组或ByteBuffer的形式获取)进行了全部处理,最后返回了Class对象。

这些Class对象大多与普通对象类似,但是您绝不能通过new创建它们;只有JVM将创建实例。此外,JVM可能会将其他信息与这些对象相关联,这些信息对于查看Java对象的应用程序程序员是不可见的。

defineClass中发生的事情是特定于实现的。但是,通常不按原样存储类文件字节。它们可能包含执行所需的信息,并且所需的信息可能不是当前平台的最佳格式(例如字节顺序和首选数据对齐方式)。此外,将不同类别的相同常数折叠到一个存储中是有意义的。由于无论如何都必须检查类数据的有效性,因此将处理步骤与将数据转换为更适合后续处理的内部格式相结合是很有意义的。

关于类的完整运行时信息仍然分布在堆(如Class实例及其关联的Reflection对象)和方法区域(如代码,链接信息,JVM内部结构等)上。请注意,这些名称是由规范指定的,即Java堆是defined as the memory area containing all Java objects,方法区是defined as the storage of the meta data。由于此区别是根据定义给出的,因此无论它对特定的实现是否有影响(毕竟,它只是RAM),您都不会在此分类中看到依赖于实现的更改。