1. 程式人生 > >jvm加載類

jvm加載類

protect min ger env -- comm system inf opera

作為jvm的用戶,從使用者角度來看,我們給jvm輸入一個class文件,得到了一個Class對象。
我們可以猜想下jvm加載類的過程:
class文件有規定的格式,jvm去解析class文件流,讀magic, major version, minor version等值(最簡單的舉例),然後生成Klass對象,並放到一個map中。

首先有個全局的認識,jvm把已加載的類放在一個hashtable中。
class SystemDictionary : AllStatic {
// Hashtable holding loaded classes.
static Dictionary* _dictionary;
};

從java.lang.ClassLoader接口的defineClass1方法作為入口,探究類加載的過程;
--> java.lang.ClassLoader/defineClass1

在ClassLoader.c文件中找到Java_java_lang_ClassLoader_defineClass1;
--> JNIEXPORT jclass JNICALL
Java_java_lang_ClassLoader_defineClass1(JNIEnv *env, jobject loader,jstring name,jbyteArray data,jint offset,jint length,jobject pd,jstring source)

--> ./hotspot/src/share/vm/prims/jvm.cpp:1049 JVM_DefineClassWithSource

--> jvm.cpp/jvm_define_class_common

--> Klass* k = SystemDictionary::resolve_from_stream(class_name, class_loader,protection_domain, &st,verify != 0,CHECK_NULL);

--> instanceKlassHandle k = ClassFileParser(st).parseClassFile(class_name,loader_data,protection_domain,parsed_name,verify,THREAD);
// We can now create the basic Klass* for this klass
--> _klass = InstanceKlass::allocate_instance_klass(loader_data,vtable_size,itable_size,info.static_field_size,total_oop_map_size2,rt,name,super_klass(),                                     !host_klass.is_null(), CHECK_(nullHandle));
--> ik = new (loader_data, size, THREAD) InstanceKlass( //這裏用到了operator new的語法
vtable_len, itable_len, static_field_size, nonstatic_oop_map_size, rt, access_flags, is_anonymous);
--> set_init_state(InstanceKlass::allocated); //狀態1

--> define_instance_class(k, THREAD);
--> add_to_hierarchy(k, CHECK);
--> k->set_init_state(InstanceKlass::loaded); //狀態2
--> k->eager_initialize(THREAD);
--> eager_initialize_impl(this_oop);
--> link_class_impl(this_oop, true, THREAD); //這裏主要是link操作
--> this_oop->set_init_state(linked); //狀態3



InstanceKlass中的枚舉:
enum ClassState {
allocated, // allocated (but not yet linked)
loaded, // loaded and inserted in class hierarchy (but not linked yet)
linked, // successfully linked/verified (but not initialized yet)
being_initialized, // currently running class initializer
fully_initialized, // initialized (successfull final state)
initialization_error // error happened during initialization
};

//設置類加載過程的狀態,通過跟蹤這個方法,能大概定位類加載的過程。
void set_init_state(ClassState state);



allocate:
parse class文件流,創建Kclass對象,並賦屬性值,在這個過程中會對class文件做簡單的verify。
常量池的解析也是在這一步。
load
具體的操作好像並不多,只是加到SystemDictionary中而已。
link
從當前類的父類開始,然後是接口,最後才是當前類;
verify 動作,是針對Klass對象,好像是對字節碼指令的合法性做校驗;
rewrite動作,










jvm加載類