为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

婷婷同学_ 2021-10-28 09:49:47
我猜较新版本的 java 将方法区和堆区合并为一个堆区。但这与旧版本有关。但是 jvm加载定义声明为“查找 .class 文件并创建 Class 对象的过程”这些是我的疑惑:当我们运行我们的 .class 文件时,它是否首先按原样存储在方法区中?完整的 .class 文件是否刚刚转换为内存位?还是只是元数据?这个“类数据”在方法区的内存分配模式究竟是什么?Classloader类是否使用Class类的方法来获取最终存储在方法区中的元数据?这些 Class 对象与我们使用 new 创建的对象相同吗?我已经查看了文档,但仍然无法弄清楚 在哪个步骤中创建了 Class 对象。 .class 文件信息是否转换为元数据并保存为方法区上的 Class 对象?我已经看过文档了。我只需要简单解释一下什么是“加载”?方法区域具有具有此元数据的类对象?或者只是整个 .class 文件的逐位信息?编辑:我也知道“编写/运行代码”本身意味着整个文件在 RAM 上都是位格式。我想知道 RAM 上的这个特殊方法区域是只有这个副本还是完全不同。
查看完整描述

2 回答

?
Cats萌萌

TA贡献1805条经验 获得超9个赞

AClassLoader只负责定位和读取类文件,并可选择将 aProtectionDomain与代码位置相关联,以支持安全措施。

然后它将字节传递给defineClass每个类加载器继承的方法之一。这些方法将类文件字节作为数组或ByteBuffer,并执行整个魔术,最终返回一个Class对象。

这些Class对象大多像普通对象,但你从来没有通过new; 只有 JVM 会创建实例。此外,JVM 可以将附加信息与这些对象相关联,这些信息对于查看 Java 对象的应用程序程序员是不可见的。

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

关于类的完整运行时信息仍然分布在堆(如Class实例及其关联的反射对象)和方法区(如代码、链接信息、JVM 内部结构等)上。请注意,这些名称由规范给出,即 Java 堆定义为包含所有 Java 对象的内存区域,方法区定义为元数据的存储。由于这种区别是由定义给出,无论它是否对特定实现产生影响(毕竟,它只是 RAM),您不会在此分类中看到依赖于实现的更改。


查看完整回答
反对 回复 2021-10-28
?
翻翻过去那场雪

TA贡献2065条经验 获得超13个赞

有关其工作原理的完整说明,您需要阅读 Java 虚拟机规范的第 5 章。介绍说,

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

回答具体问题:

  1. 类文件不是按原样加载到方法区中,而是作为类的特定实现(意味着 JVMS 不强制要求)内部表示加载。类(数组类除外)由类加载器加载。类加载器为给定的类创建一个类对象(即元数据)的实例。该对象在堆中的空间分配由 JVM 处理。

  2. 不。类加载器负责创建 Class 对象,因此不使用该对象的方法。

  3. 是的,Class 对象与任何其他 Java 对象的形式相同。Class 类继承自 Object,您可以像调用其他对象一样调用 equals、hachCode 等方法。


查看完整回答
反对 回复 2021-10-28
  • 2 回答
  • 0 关注
  • 162 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信