当前位置: 首页 > news >正文

说一下JVM类加载机制?

Java中的所有类,都需要由类加载器装载到JVM中才能运行。类加载器本身也是一个类,而它的工作就是把class文件从硬盘读取到内存中。

在写程序的时候,我们几乎不需要关心类的加载,因为这些都是隐式装载的,除非我们有特殊的用法,像是反射,就需要显式的加载所需要的类。

类装载方式,有两种 :

  1. 隐式装载, 程序在运行过程中当碰到通过new 等方式生成对象时,隐式调用类装载器加载对应的类到jvm中
  2. 显式装载, 通过class.forname()等方法,显式加载需要的类

Java类的加载是动态的,它并不会一次性将所有类全部加载后再运行,而是保证程序运行的基础类(像是基类)完全加载到jvm中,至于其他类,则在需要的时候才加载。这当然就是为了节省内存销。

JVM 类加载机制分为五个部分:加载,验证,准备,解析,初始化,下面我们就分别来看一下这五个过程


一、加载


加载是类加载过程中的一个阶段, 这个阶段会在内存中生成一个代表这个类的 java.lang.Class 对象,作为方法区这个类的各种数据的入口。注意这里不一定非得要从一个 Class 文件获取,这里既可以从ZIP 包中读取(比如从 jar 包和 war 包中读取),也可以在运行时计算生成(动态代理),也可以由其它文件生成(比如将 JSP 文件转换成对应的 Class 类)。

二、验证


这一阶段的主要目的是为了确保 Class 文件的字节流中包含的信息是否符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。

三、准备


准备阶段是正式为类变量分配内存并设置类变量的初始值阶段,即在方法区中分配这些变量所使用的内存空间。

四、解析


解析阶段是指虚拟机将常量池中的符号引用替换为直接引用的过程。符号引用就是 class 文件中的:
1. CONSTANT_Class_info
2. CONSTANT_Field_info
3. CONSTANT_Method_info
等类型的常量。
符号引用
符号引用与虚拟机实现的布局无关, 引用的目标并不一定要已经加载到内存中。 各种虚拟机实现的内存布局可以各不相同,但是它们能接受的符号引用必须是一致的,因为符号引用的字面量形式明确定义在Java 虚拟机规范的 Class 文件格式中。
直接引用
直接引用可以是指向目标的指针,相对偏移量或是一个能间接定位到目标的句柄。如果有了直接引用,那引用的目标必定已经在内存中存在。
 

五、初始化


初始化阶段是类加载最后一个阶段,前面的类加载阶段之后,除了在加载阶段可以自定义类加载器以外,其它操作都由 JVM 主导。到了初始阶段,才开始真正执行类中定义的 Java 程序代码。
 

相关文章:

  • InnoDB索引与优化篇(2)-理解InnoDB的执行计划
  • Windows预定义阴影画刷学习
  • Go语言教程
  • MyBatis的缓存机制: 一级缓存和二级缓存
  • css复习
  • spark为什么比mapreduce快?
  • 数据结构 第1章 绪论(一轮习题总结)
  • 代码随想录算法训练营第二十五天|216.组合总和III、17.电话号码的字母组合
  • Spring Boot 的参数校验方案
  • 【k8s资源调度-Deployment】
  • 【Linux】 faillock 命令使用
  • 【前端素材】推荐优质后台管理系统Sneat平台模板(附源码)
  • 如何食用Kaggle的Course中的exercise?
  • 2.22作业
  • 微服务开发工具及环境搭建
  • JavaScript-如何实现克隆(clone)函数
  • Android开源项目规范总结
  • C++类的相互关联
  • Facebook AccountKit 接入的坑点
  • input实现文字超出省略号功能
  • java多线程
  • MQ框架的比较
  • open-falcon 开发笔记(一):从零开始搭建虚拟服务器和监测环境
  • PHP 程序员也能做的 Java 开发 30分钟使用 netty 轻松打造一个高性能 websocket 服务...
  • spark本地环境的搭建到运行第一个spark程序
  • 动态规划入门(以爬楼梯为例)
  • 技术胖1-4季视频复习— (看视频笔记)
  • 浏览器缓存机制分析
  • 前端之Sass/Scss实战笔记
  • 提醒我喝水chrome插件开发指南
  • 为视图添加丝滑的水波纹
  • 智能合约Solidity教程-事件和日志(一)
  • 《码出高效》学习笔记与书中错误记录
  • ### Error querying database. Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException
  • #{}和${}的区别?
  • #微信小程序(布局、渲染层基础知识)
  • $(function(){})与(function($){....})(jQuery)的区别
  • (1)(1.11) SiK Radio v2(一)
  • (Git) gitignore基础使用
  • (pojstep1.1.1)poj 1298(直叙式模拟)
  • (附源码)springboot 校园学生兼职系统 毕业设计 742122
  • (附源码)springboot码头作业管理系统 毕业设计 341654
  • (力扣记录)235. 二叉搜索树的最近公共祖先
  • (免费分享)基于springboot,vue疗养中心管理系统
  • (一)appium-desktop定位元素原理
  • (已更新)关于Visual Studio 2019安装时VS installer无法下载文件,进度条为0,显示网络有问题的解决办法
  • (转)如何上传第三方jar包至Maven私服让maven项目可以使用第三方jar包
  • .cfg\.dat\.mak(持续补充)
  • .net 7 上传文件踩坑
  • .net Application的目录
  • .NET C#版本和.NET版本以及VS版本的对应关系
  • .Net Remoting常用部署结构
  • .net 程序发生了一个不可捕获的异常
  • .Net 应用中使用dot trace进行性能诊断
  • .NET框架