【发布时间】:2018-05-29 07:37:41
【问题描述】:
我试图了解类文件是如何加载到方法区域并执行的。我对常量池感到非常困惑。
最初创建常量池的时间是什么时候?在编译时 类文件或加载类时。
字节码在方法区是如何组织的 方法表是什么 包括?
- 任何人都可以显示草图中映射的图片表示 便于理解的方法区
【问题讨论】:
标签: java jvm classloader
我试图了解类文件是如何加载到方法区域并执行的。我对常量池感到非常困惑。
最初创建常量池的时间是什么时候?在编译时 类文件或加载类时。
字节码在方法区是如何组织的 方法表是什么 包括?
【问题讨论】:
标签: java jvm classloader
编译 Java 文件时,对变量和方法的所有引用都作为符号引用存储在类的常量池中。
【讨论】:
javap -v MyClass
到你的 MyClass.class
'javap -c -v Main'
【讨论】:
由于“常量池”的字面意思就是“常量池”,所以名字有不同的东西,容易混淆
每个类文件都有一个常量池,描述了该类中使用的所有常量,其中包括常量值以及链接所需的符号引用。一些条目同时满足这两个角色,例如类条目可用作对成员的符号引用的所有者声明,在访问字段或调用方法时需要,但也可用于获取 Class 实例,例如对于出现在源代码中的类文字。由于它是类文件的一部分,它的格式在 Java® 虚拟机规范,§4 类文件格式中指定,§4.4. The Constant Pool。
正如其他答案所说,您可以使用命令javap -v class.name 来检查一个类的常量池。
运行时有对应的数据结构,也称为run-time constant pool。由于某些值表示为运行时对象(例如,String、Class、MethodType 或 MethodHandle 类型),并且符号引用必须解析为所表示的类和成员的运行时表示,因此该结构是与在类文件中找到的字节序列不同。但是这些条目是对应的,因此每次为常量实例化一个对象或解析一个符号引用时,可以记住结果并在下次访问相同的常量条目时重用。
这并不意味着实现必须具有每个类的常量池的 1:1 表示。一个特定的实现可能会将一个类的池映射到一个共享池,该共享池用于同一类加载上下文的所有类,其中每个符号引用都解析为同一个目标。
还有字符串池,它可以看作是运行时常量池的一部分,持有对与字符串常量关联的所有String 实例的引用,以允许将所有类的所有相同字符串常量解析为相同的String实例。
【讨论】:
big endian,基于x68的系统在运行时使用little endian,字符串和符号使用modified UTF-8在字节码中编码,在运行时使用UTF-16和ISO-LATIN-1,还有现有对象的内存地址并且数据结构将在运行时使用。您可能会将其视为一个惰性复制和转换操作。