面试官:Java 类加载过程是怎么样的?






面试官:为什么HashMap 使用的时候指定容量?

以下正文:

最近在看Java虚拟机,正好看到类加载这块,所以简单记录下所学到的知识,作为笔记。

首先,我们编写好的Java代码,经过编译变成.class文件,然后类加载器把.class字节码文件加载到JVM中,接着执行我们的代码,最后将类卸载出JVM。而从类加载到虚拟机到卸载出虚拟机的这一整个生命周期总共可以分为7个步骤,分别为加载、验证、准备、解析、初始化、使用和卸载,其中验证、准备和解析又称为连接阶段。接下来简单介绍下各个阶段是干嘛的。

加载是“类加载”的第一个阶段,就是将需要用到的类对应的.class字节码文件加载到虚拟机内存,并在方法区中生成一个java.lang.Class对象,作为程序访问这个类的各种数据的访问入口。

public class Test {
    public static void main(String[] args) {
        User user = new User();
    }
}

看一下上面这段代码,经过编译会生成两个字节码文件Test.classUser.class,接着会将包含main方法的这个类加载到虚拟机内存中开始执行,当执行到User user = new User(),发现需要用到User类,就会将User.class加载到内存中。所以简单的说,当需要用到哪个类时,就回去加载哪个类,Java的自带的核心类会在虚拟机启动时就会加载,包括包含main方法的启动类。但其实,类加载也挺复杂的,只是我了解的也不深,目前就理解成这样吧,后面再深入研究。

第二阶段验证,从字面上就可以看出这个阶段是来校验加载进来的.class文件中的内容是否符合规范,毕竟编译成.class文件后还是可以人为的对这个文件进行修改,那如果改的乱七八糟,压根不符合虚拟机的规范,那虚拟机就没法执行了,所以说这一步还是比较关键的。至于如何验证,还没有研究。

准备阶段我引用《深入理解Java虚拟机》中的一句话:准备阶段是正式为类变量分配内存并设置类变量初始值的阶段,这些变量所使用的内存都将在方法区中进行分配。这也比较好理解,看下面一段代码:

public class Test {
    public static int value = 10;
}

当需要用到这个类时,会先将这个类加载到内存中,并验证字节码文件的合法性。验证通过后就会进行准备工作了,会为这个类中的类变量分配内存空间,就是上面的value变量,并给一个初始值。

注意,仅包括类变量,不包括实例变量和局部变量等,并且只是给一个初始值,int型的初始值是0,所以准备过后,value的值是0,而不是10,而真正赋值为10是在初始化阶段。我还在其它资料上看到,这一阶段也会给这个类分配内存空间,先给类分配内存,在给它里面的类变量分配内存。

解析阶段是将常量池中的符号引用替换为直接引用的过程,这一部分内容我还没搞懂,所以这里就不过多记录了,简单了解一下。

初始化阶段是类加载中核心的一步了,还是以上面的代码为例,准备阶段我们已经为value变量分配了内存空间并给了初始值,现在就是真正给value赋值的时候,把10赋给了value。如果类中还含有静态代码块,也会在这一阶段执行。这里还要一点要注意,初始化类的时候,如果父类还没加载和初始化,也会触发父类的加载和初始化。

使用就没什么好说了,初始化完就可以开始使用这个对象了。

卸载是类的生命周期中的最后一阶段,即将方法区中无用的类回收,而类需要同时满足下面3个条件才算无用的类:

  • 该类所有的实例都已经被回收,也就是Java堆中不存在该类的任何实例。
  • 加载该类的ClassLoader已经被回收。
  • 该类对应的java.lang.Class对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法。

同时满足上述3个条件的类即可回收,但不一定就会回收,可通过参数配置。

下面用一张图来简单展示类的加载流程:

以上就是Java类的加载过程,当然,只是简单的说明了一下,刚接触,还是有很多地方不清楚,先大概有一个这样的印象,后面再慢慢深入理解。







END

1.面试官:当你的JVM 堆内存溢出后,其他线程是否可继续工作?2.FullGC 40次/天到10天1次,这波JVM优化很炸裂!!3.结合代码和内存变化图,图文并茂一步步弄懂JVM的FullGC4.思考Tomcat 类加载器为什么要违背双亲委派模型?

我是技术程管家,专心做内容,不割韭菜

分享技术成长之路,不忘初心,惠泽他人终身学习,与时俱进,点赞关注不迷路

相关推荐

  • 某员工想涨薪,领导没同意,果断提了离职,过了几天hr以涨薪60%挽留让他留下...
  • “朱总,我也想留,但桌子没了啊”
  • 终于被CCF A类会议AAAI录用了!
  • 得物面试:Redis 内存碎片是什么?如何清理?
  • ICLR 2024 | Twin-sight:标签稀缺下的联邦模型鲁棒训练范式
  • 博士申请 | 香港科技大学郭嵩教授招收大语言模型/边缘智能等方向全奖博士/RA/博后
  • ICLR 2024 | 持续近端策略优化算法:人类反馈的持续强化学习
  • 发论文到底是实验重要还是idea重要?
  • 用MoE横扫99个子任务!浙大等提出全新通用机器人策略GeRM
  • 看懂网飞版「三体」!Reka Core登场:挑战GPT-4、Claude 3
  • 波士顿动力Atlas,再见!退役视频引数十万观众泪目,液压退出历史舞台
  • 革命新架构掀翻Transformer!无限上下文处理,2万亿token碾压Llama 2
  • 只要会说话,不写代码也能开发!百度又搞了一个大动作
  • AWS Batch为大规模模拟引入了多容器作业
  • 微软跨平台开发新思路:React Native 如何赋能 Office、Teams、Xbox 等应用?
  • 华为云 AI 原生应用引擎的架构与实践
  • “指标平台”掀起数智风暴:AI 对话已达 95% 准确率、100% 可解释!
  • 替代 Redis 的一场赛跑,刚刚 Linux 基金会宣布了“赢家”
  • 快手电商策略算法部-电商推荐算法内推(模型/策略hc多)
  • 瓴羊董芳英:大模型时代下的数据分析