目录
根据常量池中的信息,JVM先进行内存分配,构建出constantPoolOop对象,为其分配足够的空间来保存字节码文件信息,再进行解析工作。在加载某一个类时,从常量池中还原出类里面定义的变量和方法,将它们保存到内存中,具体在constantPoolOop对象中的tag数组(存放一些索引等)和data区,在保存数据后,根据ClassFileParser::parseClassFile()链路,一系列如魔数解析、父类、接口解析之后,便到了类变量的解析,虽然常量池解析已经把Java类的变量和方法都保存到了内存中,但这些数据还需要被JVM进一步解析,在链路中解析类变量的函数是parse_fields()。
ClassFileParser::parseClassFile()里解析完常量池,父类和接口后,接着下一步解析类变量:
void ClassFileParse::parseClassFile(constantPoolHandle cp, int length, TRAPS) {
//....
struct FieldAllocationCount fac = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
objArrayHandle fields_annotations;
typeArrayHandle fields = parse_fields(cp, access_flags.is_interface(),
&fac, &fields_annotations, CHECK_(nullHnalde));
//....
}
首先初始化一个FieldAllocationCount结构体类变量fac,该结构体里面记录了5种静态类型变量和5种非静态类型变量的数量,所以一开始全部值都设为0:
struct FieldAllocationCount {
unsigned int static_oop_count;
unsigned int static_byte_count;
unsigned int static_short_count;
unsigned int static_word_count;
unsigned int static_double_count;
unsigned int nonstatic_oop_count;
unsigned int nonstatic_byte_count;
unsigned int nonstatic_short_count;
unsigned int nonstati