bootstrap类加载原理

转载 2009年11月24日 14:53:00

转载自 Ken Wu`s Blog!

 

让我们一起跟随ClassLoader里的本地方法 findBootstrapClass(), 进入jvm执行启动类加载器加载类的内部实现。

private Class findBootstrapClass0(String name)
    throws ClassNotFoundException
    {
    check();
    if (!checkName(name))
        throw new ClassNotFoundException(name);
    return findBootstrapClass(name);
    }
 
    private native Class findBootstrapClass(String name)
    throws ClassNotFoundException;
// 摘自 j2sesrcshareclassesjavalangClassLoader.c
// 表示该函数将被 java class 以jni方式调用
JNIEXPORT jclass JNICALL
Java_java_lang_ClassLoader_findBootstrapClass(JNIEnv *env, jobject loader,
jstring classname)
{
    char *clname;
    jclass cls = 0;
    char buf[128];
 
    if (classname == NULL) {
        // 类名不能为空
        JNU_ThrowClassNotFoundException(env, 0);
        return 0;
    }
 
    // 将java的string转成unicode字符, 如果unicode字符长度不超过128
    // 则不分配内存,直接拿buf缓存来使用
    // 否则就malloc一块内存存放, 如果malloc失败, 则返回NULL
    clname = getUTF(env, classname, buf, sizeof(buf));
    if (clname == NULL) {
       // 类名为空, 说明 JVM 内存分配失败, 抛出邪恶的OOM.
       JNU_ThrowOutOfMemoryError(env, NULL);
       return NULL;
    }
 
    // 将 '.' 转换成 '/'
    VerifyFixClassname(clname);
 
    if (!VerifyClassname(clname, JNI_TRUE)) {
      // 如果指定的类名不合法, 抛出异常
      JNU_ThrowClassNotFoundException(env, clname);
      goto done;
    }
 
    // 让jvm使用启动类加载器加载类, 第四位标志0表示使用启动类加载器,
    // throwError为JNI_FALSE时抛出 ClassNotFoundException,而JNI_TRUE抛出NoClassDefFoundError
    cls = JVM_FindClassFromClassLoader(env, clname, JNI_FALSE, 0, JNI_FALSE);
 
done:
    if (clname != buf) {
       // 类名的格式有问题,且没有走buf缓存,则释放掉创建的内存, 防止内存泄漏
       free(clname);
    }
 
    return cls;
}
// 摘自 hotspotsrcsharevmprimsjvm.h
/*
* jvm.h头文件, 类似java接口的定义。
× 根据给定的classLoader来加载指定类
×
× *env JNI运行环境
× *name 类名(路径)
× init 是否需要初始化类的内部数据结构
× loader 类加载器标识
× throwError 抛出的异常类型
*/
JNIEXPORT jclass JNICALL
JVM_FindClassFromClassLoader(JNIEnv *env, const char *name, jboolean init,
jobject loader, jboolean throwError);
// 摘自 hotspotsrcsharevmprimsjvm.cpp
JVM_ENTRY(jclass, JVM_FindClassFromClassLoader(JNIEnv* env, const char* name,
     jboolean init, jobject loader,jboolean throwError))
 
JVMWrapper3("JVM_FindClassFromClassLoader %s throw %s", name,
throwError ? "error" : "exception");
 
// 确保字符串不为NULL且长度不大于 (1 << 16) -1 , 否则抛出异常
if (name == NULL || (int)strlen(name) > symbolOopDesc::max_length()) {
    if (throwError) {
       THROW_MSG_0(vmSymbols::java_lang_NoClassDefFoundError(), name);
    } else {
       THROW_MSG_0(vmSymbols::java_lang_ClassNotFoundException(), name);
    }
}
 
// 将类名放入一个hashmap, 标记符号用的, 并构造为 symbolHandle
// (注意: Handle是一种间接的, 由线程变量分配空间的类,作用是防止GC回收)
// CHECK_0是一个宏, 作用是判断是否有没有处理掉的异常, 如果有, 返回0
symbolHandle h_name = oopFactory::new_symbol_handle(name, CHECK_0);
 
// 将classLoader标识转换成JVM内部表示的数据结构, 并构造为 Handle
Handle h_loader(THREAD, JNIHandles::resolve(loader));
 
jclass result = find_class_from_class_loader(env, h_name, init, h_loader,
Handle(), throwError, thread);
 
if (TraceClassResolution && result != NULL) {
 trace_class_resolution(java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(result)));
}
 
return result;
JVM_END
// 摘自 hotspotsrcsharevmprimsjvm.cpp
jclass find_class_from_class_loader(JNIEnv* env, symbolHandle name, jboolean init, Handle loader, Handle protection_domain, jboolean throwError, TRAPS) {
 
// 生成类的内部数据结构, 核心步骤,非常复杂, 后期补充一下这里, 但是对核心逻辑没影响
klassOop klass = SystemDictionary::resolve_or_fail(name, loader, protection_domain, throwError, CHECK_0);
 
// 将类的数据结构, 构造为 KlassHandle
KlassHandle klass_handle(THREAD, klass);
 
if (init && klass_handle->oop_is_instance()) {
// 初始化类内部的数据结构
klass_handle->initialize(CHECK_0);
}
 
// 分配内存, 生成class对象
return (jclass) JNIHandles::make_local(env, klass_handle->java_mirror());
}

 

ajax异步请求数据,用bootstrap中的tree模板实现tree

后台数据格式json数据data: {"0":[{"id":1,"fatherId":0,"typeName":"测试","typeIndex":0,"typeStatus":"1"}], "1"...
  • u014051010
  • u014051010
  • 2015年11月13日 15:30
  • 4401

Java高新技术第一篇:类加载器详解

首先来了解一下字节码和class文件的区别: 我们知道,新建一个java对象的时候,JVM要将这个对象对应的字节码加载到内存中,这个字节码的原始信息存放在classpath(就是我们新建Java工程...
  • jiangwei0910410003
  • jiangwei0910410003
  • 2014年01月01日 14:45
  • 24625

Bootstrap Tree View从前端到后台的例子

Bootstrap Tree View 是一个简单而优雅的Bootstrap树形视图解决方案。 可以访问作者的 GitHub页面 了解其用法及更多信息。 https://github.com/j...
  • xs_challenge
  • xs_challenge
  • 2017年08月03日 23:44
  • 2141

ClassLoader类加载机制和原理详解

  • 2009年07月07日 13:33
  • 23KB
  • 下载

Java类加载原理解析.rar

  • 2009年10月10日 16:22
  • 105KB
  • 下载

Java类加载原理解析文档

  • 2009年04月25日 11:29
  • 118KB
  • 下载

Java类加载原理解析

  • 2009年01月04日 16:15
  • 169KB
  • 下载

Java类加载原理解析

  • 2010年06月12日 22:53
  • 252KB
  • 下载

Android热修复技术(三)-----代码修复之冷启动类加载原理

前一篇博客阐述了代码修复之底层替换原理,这篇文章主要讨论代码修复之冷启动加载原理。因为底层替换方案的根本原理是基于native层的方法的替换,具有很大的局限性,不能新增减少类的方法和字段的数目,而冷加...
  • u011376022
  • u011376022
  • 2017年07月11日 23:10
  • 347

JVM类加载原理学习笔记

(1)类的生命周期包括了:加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Usin...
  • yangchunlu0101
  • yangchunlu0101
  • 2017年07月16日 20:57
  • 48355
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:bootstrap类加载原理
举报原因:
原因补充:

(最多只允许输入30个字)