JVM使用一个constantPoolOop来保存常量池的信息,而该类保存数据的是属于typeArrayOop类型的_tags对象
在ClassFileParser::parse_constant_pool()中,通过下面这行代码实现常量池分配(第一个参数length在javac编译计算出.)
constantPoolOop constant_pool = oopFactory::new_constantPool(length,oopDesc::IsSafeConc,CHECK_(nullHandle));
- 在堆中分配空间,通过object_space()->allocate(word_size)
- 初始化对象,调用init_obj(),只是清零
- 初始化oop,调用post_allocation_install_obj_klass()初始化oop并赋值
Java字节码中一切皆对象.分配空间的操作都在oopFactory中,先获取对应的klass类描述对象,然后分配al
// This version requires locking. */
HeapWord* MutableSpace::allocate(size_t size) {
assert(Heap_lock->owned_by_self() ||
(SafepointSynchronize::is_at_safepoint() &&
Thread::current()->is_VM_thread()),
"not locked");
HeapWord* obj = top();
if (pointer_delta(end(), obj) >= size) {
HeapWord* new_top = obj + size;//开空间
set_top(new_top);
assert(is_object_aligned((intptr_t)obj) && is_object_aligned((intptr_t)new_top),
"checking alignment");
return obj;//返回最初的top()
} else {
return NULL;
}
}
constantPoolOopDesc本身包含8个字段,父类两个
typeArrayOop _tags;
constantPoolCacheOop _cache;
klassOop _pool_holder;
typeArrayOop _operands;
int _flags;
int _length;
volatile bool _is_conc_safe;
int _orig_length;
//.......
volatile markOop _mark;
union _metadata{
wideKlassOop _klass;
narrowOop _compressed_klass;
} _metadata;
int object_size(int length){//真正分配的size由这个函数计算
return align_object_size(header_size() + length);
}
最终JVM会分配(40 + length)*4字节的内存大小(32位机)
constantPoolOop内存空间布局
在JVM内部,几乎所有的对象都是这种布局,对象头+实例数据
初始化内存
即清零
oop-klass模型
解析对应类型
void ClassFileParser::parse_constant_pool_entries(constantPoolHandle cp, int length, TRAPS){
//...
for (int index = 1; index < length; index++){
u1 tag = cfs->get_u1_fast();
switch(tag){
case JVM_CONSTANT_Fieldref:
{
cfs->guarantee_more(5, CHECK);
u2 class_index = cfs->get_u2_fast();
us name_and_type_index = cfs->get_u2_fast();
cp->field_at_put(index, class_index, name_and_type_index);
}
break;
//...
}
}
}