java jvm 加载_Jvm是如何加载Java类的?
前言
我们知道Java语言的类型可以分为两大类:基本类型「primitive types」和引用类型「reference types」.
对于Java的基本数据类型是Java虚拟机定义好的.至于另一大类「引用数据类型」, Java将其分为四种类型:类
接口
数组
泛型参数
由于「泛型参数」在编译时期会被擦除, 因此Java虚拟机的类型实际上只有三种.
在类、接口、数组当中,「数组」是由Java虚拟机直接生成的, 类、接口则有对应的「字节流」.
最常见的字节流则属于由Java编译器生成的「class」文件.除此之外我们还可以在程序内部生成、直接从网络当中获取(如applet)的字节流.
这此不同形式的「字节流」都会被加载到Java虚拟机中, 成为类或者接口.
加载过程
从.class文件中的类到内存里的类, 按先后顺序需要经过加载、链接、初始化三个过程.
其中「链接过程」当中还需要进行验证.
内存中的类没有经过初始化,同样是不能能使用.
加载
「查找」是为了查找字节流,并且据此创建类的过程.对于数组来说,是没有字节流的,而是由Java虚拟机直接生成的对于其它类型来说, Java虚拟机则需要借助类加载器来完成查找字节流的的过程.
加载器bootstrapClassLoader(启动类加载器)最顶层的加载器,由c++实现
负责加载%JAVA_HOME%/lib目录下的jar包和类,或者被-Xbootclasspath参数指定的路径中的所有的类.
2. 扩展类加载器「Extension Class Loader」继承于java.lang.ClassLoader
主要负责加载%JAVA_HOME%/lib/ext/下的jar包和类,或者被java.ext.dirs系统变量所指定的路径下的jar包.
3. 应用类加载器「Application Class Loader」继承于java.lang.ClassLoader
面向用户的类加载器
负责加载当前应用classpath下的jar和类.
双亲委派模型双亲委派模型每一个类都有它对应的类加载器.
系统中的ClassLoader在协同的时候会默认启用双亲委派模型.
在类加载的过程中,首先会判断这个类是否被加载过.
被加载过 -> 直接返回
没有被加载过 -> 尝试加载
加载流程先把加载类的请求委派给该父类加载器的loadClass进行处理.
因此所有的请求最终都应该传送到最顶层的类加载器BootstrapClassLoader中.
当父类无法处理时,才需要自己处理.
当父类加载器为null时,会使用BootstrapClassLoader作为其父类加载器
双亲委派模型的优点保证了java的稳定的运行, 可以保证类不被重复加载.
jvm区分不同的类不仅仅是根据全类名, 相同的类文件被不同的类加载器加载产生的也是两个不同的类.
保证java核心api不被修改.
链接
将创建的类合成至Java虚拟机中,使之能够被执行的过程.它可以分为验证、准备及解析三个过程.验证阶段的目的是为了确保被加载的类满足虚拟机的约束条件.
准备阶段的目的是为了被加载类的字段分配内存.
Java代码中对静态字段的具体初始化则会在稍后的初始化阶段进行.
构造其它跟类层次相关的数据结构.比如说用来实现虚方法的动态绑定的方法表.
解析阶段的目的是,将符号引用解析成为实际引用.
如果符号引用指向一个未被加载的类、或者未被加载类的字段或方法,那么解析将触发这个类的加载(但未必触发这个类的链接以及初始化)
初始化
为标记为常量值的字段赋值,以及执行方法的过程.
java虚拟机会通过加锁来确保类的方法仅被执行一次.
只有当初始化完成之后,类才正式成为可执行状态.
类的初始化触发情况当虚拟机启动的时候,初始化用户指定的主类.
当遇到用以新建目标类实例的new指令的时候,初始化new指令的目标类.
当遇到调用静态方法时,初始化该类的静态字段.
当遇到访问静态字段的指令时,初始化该静态字段所在的类.
子类的初始化会触发父类的初始化.
如果一个接口定义default方法,那么直接实现或者间接实现该接口的类的初始化,会触发该接口的初始化.
使用反射api对某个类进行反射调用时,初始化这个类.
当初次调用MethodHandle实例时,初始化该MethodHandle指向的方法所在的类.
java jvm 加载_Jvm是如何加载Java类的?相关推荐
- java 获取内存大小_JVM面试题扩展:Java代码在JVM中的执行流程
代码示例: public class Test { // 常量 public static final String MAN_SEX_TYPE = "man"; // 静态变量 p ...
- java jvm 查看内存_JVM:查看java内存情况命令
jinfo:可以输出并修改运行时的java 进程的opts. jps:与unix上的ps类似,用来显示本地的java进程,可以查看本地运行着几个java程序,并显示他们的进程号. jstat:一个极强 ...
- java jvm内存分配_JVM系列一:JVM内存组成及分配
java内存组成介绍:堆(Heap)和非堆(Non-heap)内存 按照官方的说法:"Java 虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配.堆是在 Java 虚 ...
- java jvm 查看内存_JVM内存状况查看方法和分析工具(下)
从以上信息中可看出JVM堆的配置信息,如NewSize.NewRatio.SurvivorRatio等:JVM堆的使用情况,新生代中的Eden Space.From Space.To Space的使用 ...
- java中Mark接口_JVM源码分析之Java对象头实现
原标题:JVM源码分析之Java对象头实现 原创申明:本文由公众号[猿灯塔]原创,转载请说明出处标注 "365篇原创计划"第十一篇. 今天呢!灯塔君跟大家讲: JVM源码分析之Ja ...
- Java Jvm虚拟机的内存模型概述 《对Java的分析总结》(一)
<对Java的分析总结>-Java虚拟机的内存模型 ** 你可能需要 CSDN 网易云课堂教程 掘金 EDU学院教程 知乎 Flutter系列文章 头条同步 百度同步 本文章首发于微信公众 ...
- Java JVM 虚拟机编译器性能增强优化技术
专栏原创出处:github-源笔记文件 ,github-源码 ,欢迎 Star,转载请附上原文出处链接和本声明. Java JVM-虚拟机专栏系列笔记,系统性学习可访问个人复盘笔记-技术博客 Java ...
- Java—JVM加载机制
编程语言有两种: 1.编译型语言 将代码一次性编译成计算机可识别的二进制文件,语言有C和C++ 2.解释型语言 通过解释器,一行行读取我们编写的代码转换成二进制数据后执行, ...
- jvm类加载过程_JVM类生命周期概述:加载时机与加载过程
作者:菜鸟小于 https://www.cnblogs.com/Young111/p/11359700.html 一个.java文件在编译后会形成相应的一个或多个Class文件,这些Class文件中描 ...
最新文章
- 华岩资本--微生物领域项目投递通道
- 关于机器学习和AI的区别最经典的解释
- 使用libssh2连接到远程服务器
- centos7根据进程号查看进程位置
- java桥接和装饰_设计模式:桥接模式和装饰模式
- Reporting Services 错误案例一则
- python中怎么表示整数的点称为整点_智慧职教云课堂APPPython程序设计基础答案公众号...
- 2018蓝桥杯省赛---java---B---1(第几天)
- matplotlib plt.scatter
- 【数学建模】基于matlab时变参数随机波动率向量自回归模型(TVP-VAR)【含Matlab源码 037期】
- android源码学习之源码编译并nexus s真机刷机
- html如何让标签居中显示,HTML怎么让标签居中
- 好用的python工具_Python哪些工具好用?老男孩Python开发
- 寒假刷刷算法题(13)
- STM32毕业设计项目
- 预留度数Rx表达式的推导
- 信号与系统_第1章 信号与系统
- FFMPEG截图 RTMP直播流
- 《云端软件平台》运行机制浅析
- 扫描识别工具Dynamic Web TWAIN使用教程:如何自定义扫描设置
热门文章
- docker 磁盘问题:device or resource busy
- 【新年巨献】计算机类国际英文EI(JA)期刊限量推荐
- Spring中BeanFactory和FactoryBean的区别
- Java线程CAS原子操作
- Spring的@Autowired和@Resource
- Linux ftp传送问题 WARNING! 258831 bare linefeeds received in ASCII mode
- linux安装指定版本python_ubuntu多版本python为指定版本python安装库
- linux下的文件系统,Linux根文件系统(“/”文件系统)下的目录介绍
- 后台窗口截图_万人拥捧的截图软件来啦!让你的工作效率提升不止一倍!
- python文件封装成jar_【Python】Python文件打包为可执行文件