暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

面试官对于JVM类加载机制的猛烈炮火,你能顶得住吗?

AlwaysBeCoding 2020-02-07
386

JVM类加载面试题


面试官一般会问JVM类加载相关的问题,面试题如下:


  1. 说说Java类加载机制?

  2. 如果加了final,是在类加载的什么时候分配的?

  3. Java类加载器有哪些,为什么使用双亲委派模型?

  4. 什么时候会加载一个类?


Java类加载机制思维导图


什么是类加载机制?


虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制


类加载的时机


类从被加载到虚拟机内存中到卸载出内存为止的生命周期7个阶段:加载、连接(验证,准备,解析)、初始化、使用、卸载



其中 加载、验证、准备、解析、卸载的顺序是确定的。初始化的顺序是不确定的,那什么情况下一个类会进行初始化呢?


根据虚拟机规范规定,有5种情况需要对类立即初始化:


  • 遇到 new getstatic putstatic 或invokestatic这4条指令码的时候

  • 使用java.lang.reflect包的方法对类进行反射调用的时候

  • 初始化一个类的时候,如果发现他的父类还没有初始化,那么先要初始化他的父类

  • 虚拟机启动时,用户需要指定一个要执行的主类(包含main()方法的那个类),虚拟机会先初始化这个类

  • 当使用jdk的动态语言支持时,如果一个java.lang.invoke.MethodHandle实例最后的解析结果REF_getStatic 、REF_putStatic、REF_invokeStatic的方法句柄,并且这个方法句柄对应的类没有进行过初始化,则需要触发其初始化


以上5种行为也被统称为主动引用。有主动引用就有被动引用,被动引用就是除了以上5种行为以外所有引用类的地方都不出触发初始化。


示例:

  • 通过子类引用父类的静态字段,不会导致子类初始化

  • 通过数组定义类引用类,不会触发此类的初始化

  • 常量在编译阶段会存入调用类的常量池种,本质上并没有直接引用到定义常量的类,因此不会触发定义常量的类的初始化


接口初始化与类是存在区别的,区别就是上边5种行为种中的第3种,区别如下:

类:当一个类初始化的时候要求其父类全部初始化

接口:接口初始化时并不要求其父类全部完成初始化,仅当真正使用到父接口的时候(如引用接口中定义的常量)才会初始化


类加载的过程


前边已经说过类加载生命周期的7个阶段,其中加载、连接(验证,准备,解析),初始化是在运行期进行的。


运行期特性:


加载阶段:


加载完成后,二进制流按虚拟机格式存储在方法区


验证阶段:


确保Class文件的字节流中的信息符合虚拟机的要求

不会危害虚拟机自身安全

本阶段会大致完成下面4个阶段的验证动作:

准备阶段:

为类变量(被static修饰的变量)分配内存,并设置初始值

被final修饰的类变量初始值设置为指定的值


解析阶段:

虚拟机将常量池中的符号引用替换为直接引用的过程


初始化阶段:

类加载过程最后一步,前边已经说过类加载的时机,需要掌握


类加载器和双亲委派模型


类加载器有四种:


启动类加载器:

虚拟机本身的,c++语言实现的

加载java_home/lib下的类

加载 -Xbootclasspath指定路径下的类

系统属性sun.boot.class.path指定目录下的jar包


扩展类加载器(Extension ClassLoader):

加载java_home/lib/ext下的类

加载被java.ext.dirs系统变量所指定路径下的类


应用程序类加载器(Application ClassLoader):

由 Sun的 AppClassLoader(sun.misc.Launcher$AppClassLoader)实现的。它负责将系统类路径java -classpath或-Djava.class.path变量所指的目录下的类库加载到内存中。开发者可以直接使用系统类加载器。


双亲委派模型:

以上这种层次关系被称为双亲委派模型

注:非强制约束模型,只是一种推荐模型


工作过程:


如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把请求委托给父加载器去完成,依次向上,因此,所有的类加载请求最终都应该被传递到顶层的启动类加载器中,只有当父加载器在它的搜索范围中没有找到所需的类时,即无法完成该加载,子加载器才会尝试自己去加载该类


总结


以上就是与Java类加载机制相关知识点的笔记,最后留个问题:扩展类加载器的父加载器是启动类加载器吗?


文章转载自AlwaysBeCoding,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论