尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
JVM 类加载
目录一、JDK组成二、javac1.编译目的2.编程语言分类3.编译过程4.Class文件三、类加载器1.类型2.双亲委派模式3.类加载过程4.自定义类加载器一、JDK组成Java开发工具包用于编译和运行Java程序包括内置类库.java用于编写java文件编译器javac 将java文件编译成class文件调试工具jmap、jstackJava运行环境JRE包括编译后的内置类库.class虚拟机JVM 用于执行class文件不同OS有不同的JVM实现二、javac1.编译目的编译的目标是将源代码转换为OS可执行的二进制指令常见的javac有IDEA、Eclipse。解释型语言在运行阶段编译会拖慢运行速度编译型语言在部署时编译部署时间长。为了解决上述两种语言的问题Java将编译过程分为预编译、后编译两部分javac负责预编译生成不同JVM通用的class文件。JVM负责后编译针对不同OS开发了特定的JVM用于生成OS可执行的二进制指令。2.编程语言分类编译型语言编译器在客户机的**部署时编译(程序应装入内存才能链接)**将源代码一次性翻译成OS可执行的机器码例如C、Go运行阶段速度快但部署时间长。解释型语言运行时编译解释器在运行阶段将源代码翻译为机器码将编译时间分摊到运行阶段没有部署时间但是运行时间较长。Java、Python语言属于编译解释型语言为了消除部署时间并减少运行时间将校验等操作解耦到部署前编译编译后的文件可以在客户机上直接部署也没有部署时间但是编译阶段不在客户机上所以类并没有具体内存地址链接阶段还是需要在运行时编译。3.编译过程词法分析将源代码拆分为token检查单个token是否符合约束。语法分析根据执行顺序基于token构造语法树检查语法是否正确。填充符号表类之间是相互引用的由于预编译阶段类、接口并未装入内存就需要以符号的形式记录类,符号(表示内存地址)到符号表同时检查是否有循环依赖。注解处理处理Override等编译时注解部分注解会修改语法树。语义分析遍历语法树进行类型检查、变量作用域检查。字节码生成遍历语法树将语法节点映射为JVM字节码指令例如变量赋值ldc、if判断if_icmpge同属性、方法、常量、引用记录到class文件。4.Class文件ClassFile{u4 magic;//Class 文件的标志u2 minor_version;//Class 的小版本号u2 major_version;//Class 的大版本号u2 constant_pool_count;//常量池的数量cp_info constant_pool[constant_pool_count-1];//常量池u2 access_flags;//Class 的访问标记u2 this_class;//当前类u2 super_class;//父类u2 interfaces_count;//接口数量u2 interfaces[interfaces_count];//一个类可以实现多个接口u2 fields_count;//字段数量field_info fields[fields_count];//一个类可以有多个字段u2 methods_count;//方法数量method_info methods[methods_count];//一个类可以有多个方法u2 attributes_count;//此类的属性表中的属性数attribute_info attributes[attributes_count];//属性表集合}class文件主要属性有vesion版本号用于记录程序编写时基于的JDK版本高版本JVM可以后编译低版本class文件但是低版本JVM无法编译高版本class文件。constant_pool常量池记录预编译阶段符号填充表的二进制等到真正确定内存地址JVM会检查符号表将符号转换为类、对象真正的内存地址。access_flags访问标记记录类的元信息包括类型、作用域等每个组合都对应一个二进制。fields属性表记录类的成员变量元信息包括作用域、返回值类性、可变性、可见性等每个组合都对应一个二进制。methods方法表记录类的方法元信息包括作用域、返回值类型、参数等内部还有一个attributes数组记录方法体中的二进制指令序列。三、类加载器1.类型类加载器负责将磁盘中的class文件加载到内存中。JVM 启动时并不会一次性加载所有的类而是根据需要去动态加载。BootstrapClassLoader是最顶层的类加载器用来加载JDK的类库。AppClassLoader负责加载应用中的引入的第三方类库和自定义类。2.双亲委派模式每个类加载器都维护一个HashMap记录全限定类名Class对象加载前先检查Map所以同一个ClassLoader相同全限定类名只会被加载一次但是不同ClassLoader可能会重复加载同一个类这就有类的重复加载问题。双亲委派模型会先将类加载请求转发给父类加载器在父类加载器没有找到所请求的类的情况下该类加载器才会尝试去加载确保了不会有重复加载问题。此外双亲委派模型还能防止核心API被篡改当项目中有多个String.class类时委派BootstrapClassLoader加载JDK中的String类防止AppClassLoader加载自定义的String类。3.类加载过程当访问的类不在内存中即内存中没有该类的Class对象就会触发类加载装入类加载器装入class文件到内存方法区并在堆中实例化Class对象作为访问方法区的入口。链接验证class版本号是否低于JVM版本号为static变量分配内存空间并赋初始值。final类型直接赋给定值。Java采用运行时动态链接将类中的符号引用替换为方法区中方法和类或接口的直接引用。这样当处理器执行一条指令时就能知道应该读取哪个内存空间中的对象数据并操作。初始化同一个类的初始化仅执行一次触发时机为类被new、调用静态变量静态方法、子类被加载、反射操作类时。初始化会执行类的静态代码块并为static变量赋指定值。特别的main方法对应的类在JVM进程启动时就会初始化。4.自定义类加载器一个Tomcat服务器对应一个JVM进程当Tomcat服务器中部署订单系统、库存系统等多个系统且不同系统中存在全类名相同的文件时使用一个类加载器就无法加载这些全类名相同的问题就要用到自定义类加载器打破双亲委派机制。每个系统使用自己的类加载器加载文件类加载时不进行双亲委派而是直接自己加载从而达到应用之间的类隔离。继承ClassLoader抽象类重写以下方法findClass(String name)给定要加载的类的二进制名称重写该方法后默认还是双亲委派机制先调用父加载器loadClass()方法加载如果加载失败才调用该方法内的逻辑加载。loadClass(String name, boolean resolve)重写该方法后类加载器会首先尝试自己加载name类。
RELATED

相关推荐

数字滚动动效:从requestAnimationFrame到Vue组件的完整实现

数字滚动动效:从requestAnimationFrame到Vue组件的完整实现

1. 从静态数字到动态表达:为什么我们需要数字滚动动效? 在后台管理、数据大屏或者任何需要展示关键指标的地方,我们常常会看到这样的场景:一个数字,比如“总销售额”或“在线用户数”,它不是直接显示最终值…

📅 2026/9/30 11:19:37
WeatherBench终极指南:三步搞定数据驱动天气预报基准测试

WeatherBench终极指南:三步搞定数据驱动天气预报基准测试

WeatherBench终极指南:三步搞定数据驱动天气预报基准测试 【免费下载链接】WeatherBench A benchmark dataset for data-driven weather forecasting 项目地址: https://gitcode.com/gh_mirrors/we/WeatherBench 想要快速评估天气预报模型性能?We…

📅 2026/8/24 13:52:48
Git 实用操作指南

Git 实用操作指南

Git 实用操作全指南:从基础到进阶 学习 Git 最权威的资料是其官方文档,推荐优先查阅:Git 官方文档(中文版)。本文整理了日常开发中高频使用的 Git 命令,按核心场景分类,方便我快速查阅和使用。…

📅 2026/9/16 14:12:28
MORE NEWS

更多资讯

📰

SSM员工考勤管理系统设计与部署全流程详解

考勤管理系统在Java课程设计和毕业设计里几乎是"永不过时"的选题。每年都能看到大量"java_ssm员工考勤管理系统"相关的需求,但这个题目其实可以做得很有深度。我手上这套基于SSM(Spring SpringMVC MyBatis)的员工考勤管…

📰

SSM实战:儿童教育PTC管理系统设计与开发全解析

如果你最近也在找一个能写进简历、又能顺利通过课程验收的Java项目,我强烈建议你研究一下“儿童教育在线学习系统PTC管理系统”这种题材。它表面上是普通的SSM三件套项目——Spring管理业务对象、SpringMVC处理请求分发、MyBatis操作数据库,但真正有意思…

📰

讲解设备验厂看哪些环节,无线讲解器产线与品控的技术清单

海外客户到厂验线,跟审厂、跟单都不太一样。他们不是来看产能数字的,是来把工艺细节摊开问的。问什么、看什么、凭什么判断,其实有一条相对固定的路径。我把这条路径整理成一份清单,给需要接待验厂或者准备海外交付的人做参考&…

📰

苍穹外卖day11:统计报表与Excel导出的核心实现与避坑指南

如果你也正在做一个前后端分离的外卖项目,那“苍穹外卖--day11”这个节点一定不陌生。到了第11天,业务闭环基本已经打通:员工登录、分类菜品、套餐管理、购物车、订单流转这些模块都有了,接下来要面对的就不再是单纯的增删改查&am…

📰

苍穹外卖day11核心拆解:购物车、下单事务与库存防超卖实战

先说个结论:按常见的外卖项目推进节奏,day11差不多是“前端管理端基础功能收尾、用户端点餐链路正式启动”的分水岭。到了这个节点,你已经不太需要纠结环境搭建和简单的CRUD了,真正开始碰一个外卖系统的核心:购物车、下…

📰

Redis远程连接配置详解:从默认限制到安全加固

做后端开发的,基本都绕不开Redis。平时在本地开发环境用得顺手,一部署到服务器或者需要跨机器访问的时候,往往会卡在一个很基础的问题上——明明Redis进程跑得好好的,在服务器上连接、读写一切正常,可换到另一台机器上…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬