重读《深入理解Java虚拟机》四、虚拟机如何加载Class文件
1、Java语言的特性
Java代码经过编译器编译成Class文件(字节码)后,就需要虚拟机将其加载到内存里面执行字节码所定义的代码实现程序开发设定的功能。
Java语言中类型的加载、连接(验证、准备、解析)、初始化都是在程序运行期间内完成的与C++不同(C++在编译期就需要进行连接),这样也使得Java语言更具灵活性。
2、虚拟机类加载的过程
(1)虚拟机什么时候进行类的加载(类加载的时机)
1)遇到new、getstatic、putstatic或者invokestatic 这四条字节码指令的时候,且该类没有进行初始化则进行该类的初始化
2)使用反射机制的时候
3)初始化类的父类
4)初始化虚拟机要执行主类
5)使用动态语言特性的时候
即当对一个类进行主动引用的时候,就会进行初始化操作,而进行被动引用的时候不进行初始化操作。
被动引用有:
a.通过子类引用父类静态字段,子类不会被初始化;
b.引用类数组不会初始化该类
c.定义常量的类被调用的时候不会被初始化,因为常量的值已经在编译期的时候就已经存储在调用类的常量池里面了。
(2)类的加载过程
1)加载
加载过程主要是发生在虚拟机外由单独的类加载器对指定的二进制字节流加载到内存(方法区)的过程,也就是Class文件的存储结构转换成内存方法区内的运行时数据结构并生成一个对应Class实例对象的过程。
2)验证
二进制字节流加载到内存后,需要对当前文件信息和格式等进行验证,包括文件格式的验证、元信息的验证、字节码验证、符号引用验证。
3)准备
已经加载到内存方法区内的类信息等经过验证通过后就需要在内存上分配指定大小的内存空间和进行自动化初始化操作(将各个类型字段设置默认值)。静态变量在这个阶段进行内存分配。准备阶段为类变量分配内存空间和设置变量初始默认值,但是这个阶段不包括局部变量的初始值设置。
4)解析
将Class文件内常量池定义的符号引用转换成直接引用,完成类信息,字段、方法等在内存上的布局
5)初始化
执行类构造器<clinit>方法的过程,变量的声明初始化在这个阶段进行。

3、接口的加载
接口的加载过程有别于类的加载过程,接口也有自己的初始化过程,用于初始化接口中所定义的成员变量。
类的加载过程的中先执行父类的加载然后再执行子类的加载,也就是要确保类的父类都已经加载了,但是接口的加载不要求其父接口进行初始化,只用真正用到父类接口的时候才进行父类的初始化。
重读《深入理解Java虚拟机》四、虚拟机如何加载Class文件的更多相关文章
- 【Java基础】通过getResourceAsStream() 加载资源文件
Class.getResourceAsStream(String path) path不以"/"开头时,默认是从当前类所在的包下面获取资源 path以"/"开头 ...
- [改善Java代码]使用forName动态加载类文件
动态加载(Dynamic Loading)是指在程序运行时加载需要的类库文件,对Java程序来说,一般情况下,一个类文件在启动时或首次初始化时会被加载到内存中,而反射则可以在运行时再决定是否需要加载一 ...
- 【java虚拟机系列】java中类与对象的加载顺序
首先了解一下Java虚拟机初始化的原理. JVM通过加装.连接和初始化一个Java类型,使该类型可以被正在运行的Java程序所使用.类型的生命周期如下图所示: 装载和连接必须在初始化之前就要完成. 类 ...
- 深入java虚拟机学习 -- 类的加载机制
当看到"类的加载机制",肯定很多人都在想我平时也不接触啊,工作中无非就是写代码,不会了可以百度,至于类,jvm是怎么加载的我一点也不需要关心.在我刚开始工作的时候也觉得这些底层的内 ...
- 深入java虚拟机学习 -- 类的加载机制(续)
昨晚写 深入java虚拟机学习 -- 类的加载机制 都到1点半了,由于第二天还要工作,没有将上篇文章中的demo讲解写出来,今天抽时间补上昨晚的例子讲解. 这里我先把昨天的两份代码贴过来,重新看下: ...
- 深入java虚拟机学习 -- 类的加载机制(三)
类的初始化时机 在上篇文章中讲到了类的六种主动使用方式,反射是其中的一种(Class.forName("com.jack.test")),这里需要注意一点:当调用ClasLoade ...
- windows/tomcat 修改java虚拟机JVM以utf-8字符集加载class文件的两种方式
1.情景展示 做了这么长时间的java开发,但是,你知道JVM是以怎样的编码加载.解析class文件的吗? 我们知道,通常情况下,我们会将java文件的字符集修改成utf-8,这样,理所当然地就认 ...
- Java提高篇——JVM加载class文件的原理机制
在面试java工程师的时候,这道题经常被问到,故需特别注意. 1.JVM 简介 JVM 是我们Javaer 的最基本功底了,刚开始学Java 的时候,一般都是从“Hello World ”开始的,然后 ...
- java类到底是如何加载并初始化的?
Java虚拟机如何把编译好的.class文件加载到虚拟机里面?加载之后如何初始化类?静态类变量和实例类变量的初始化过程是否相同,分别是如何初始化的呢?这篇文章就 是解决上面3个问题的. 若有不正之处, ...
随机推荐
- AI金融知识自学偏量化方向-前提1
前提: 统计学习(统计分析)和机器学习之间的区别 金融公司采用机器学习技术及招募相关人才要求 第一个问题: 机器学习和统计学都是数据科学的一部分.机器学习中的学习一词表示算法依赖于一些数据(被用作训 ...
- 如何在wiced平台上编译,运行智能彩灯 实时控制彩灯的色调和开关
https://github.com/WildDogTeam/demo-c-rgblight/tree/master/src/device 恢复出厂的GPIO口在demo_platform.h声明为W ...
- 设置gem源,解决下载慢的问题
问题解决的最好方法方法 使用google的DNS 8.8.8.8 / 8.8.4.4 另一种解决方式 修改rubygems的source源 $ gem source -r http://rubygem ...
- Springboot学习笔记(五)-条件化注入
前言 将Bean交给spring托管很简单,根据功能在类上添加@Component,@Service,@Controller等等都行,如果是第三方类,也可以通过标有@Configuration的配置类 ...
- [Full-stack] 快速上手开发 - React
故事背景 [1] 博客笔记结合<React快速上手开发>再次系统地.全面地走一遍. [2] React JS Tutorials:包含了JS --> React --> Red ...
- QT下载区
http://download.qt.io/archive/qt/ 下载总网址: http://download.qt.io/ http://mirrors.hust.edu.cn/qtproject ...
- [Android] 基于 Linux 命令行构建 Android 应用(七):自动化构建
本章将演示如何基于 Linux 命令行构建 Android 应用,在开始本章之前,希望你已经阅读之前几章内容. 本文环境为 RHEL Sandiego 32-bits,要基于 Linux CLI 构建 ...
- Git-简单的利用SourceTree提交代码
解决办法: 小编也是新手,所以在使用SourceTree上面花了不少时间,好在简单的拉去远程代码,同步本地仓库代码搞定了.下面是步骤: 1.我们先去下载一个SourceTree然后打开. 2.下一步, ...
- 128、View 绘制流程 & 自定义View
记清楚函数调用的顺序才能准确地进行调用. 根据调用链,可将整个绘制过程分为三部分:Measure - Layout - Draw Measure 过程 1. 测量过程由上至下,在measure过程的最 ...
- VI/VIM 无法使用系统剪贴板(clipboard)?(Ubuntu&Mac OS X已解决)
在 Ubuntu/Mac OS X 中使用VI/VIM时,发现无法使用系统的剪贴板. Ubuntu 上网一查,原来是少装了几个东西. 使用如下命令,安装相关的包.安装成功后,就可以使用系统剪贴板了. ...