加载过程

JVM学习笔记(二):类加载

  • Loading
    1、双亲委派
    JVM学习笔记(二):类加载
    为什么要做双亲委派:主要是出于安全考虑。举个例子如果没有双亲委派,我们自定义一个类加载器,再定义一个类名字为
    java.lang.String,直接把oracle定义的String类覆盖,并把它交给我们自定义的类加载器,让它去加载。我们把自定义的类加载器和java.lang.String打包为一个jar,交给客户。这时,我们就可以动手脚获取用户的敏感信息了。显然这是不安全的。
    **双亲委派加载过程:**如果我们自定义了类加载器,那么当一个类被加载的时候,首先会交给Custom ClassLoader,他去他的缓存中去寻找是否有该类,没有就交给父加载器App,App拿到这个类之后同样去缓存中去寻找是否有该类 … … 以此类推直到顶层Bootstrap,如果他在缓存没找到该类,那么他会尝试去加载这个类,看这个类是不是rt.jar等核心类,不是的话则交给Extension,Extension拿到这个类,去看这个类是不是jre/lib/ext/*.jar,不是的话继续向下委托,如果直到Custom ClassLoader都没找到这个类,那么直接抛NPE异常,找到就返回。
    2、LazyLoading
    (1)new getstatic putstatic invokestatic指令,访问final变量除外
    (2)java.lang.reflect对类进行反射调用时
    (3)初始化子类的时候,父类首先初始化
    (4)虚拟机启动时,被执行的主类必须初始化
    (5)动态语言支持java.lang.invoke.MethodHandle解析的结果为REF_getstatic REF_putstatic REF_invokestatic的方法句柄时,该类必须初始化
    3、自定义类加载器:通过观看源码可以知道,ClassLoader采用了钩子函数,模版方法设计模式,因此我们只需要继承ClassLoader,重写findclass方法就可以了。
    4、java是解释编译混合性语言,java有自己的解释器Interpreter,以及即时编译器JIT。一个程序在运行时,先进行解释执行,执行过程中它会对代码进行热点检测,对于方法有一个方法计数器,对于循环有一个循环计数器,当方法或者循环执行频率过高时(编译阈值为10000),就会对这段代码进行编译
  • linking
    1、Verification
    2、Preparation
    3、Resolution
  • Initializing
------------- TO BE UPDATED --------------

相关文章: