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文件的更多相关文章

  1. 【Java基础】通过getResourceAsStream() 加载资源文件

    Class.getResourceAsStream(String path) path不以"/"开头时,默认是从当前类所在的包下面获取资源 path以"/"开头 ...

  2. [改善Java代码]使用forName动态加载类文件

    动态加载(Dynamic Loading)是指在程序运行时加载需要的类库文件,对Java程序来说,一般情况下,一个类文件在启动时或首次初始化时会被加载到内存中,而反射则可以在运行时再决定是否需要加载一 ...

  3. 【java虚拟机系列】java中类与对象的加载顺序

    首先了解一下Java虚拟机初始化的原理. JVM通过加装.连接和初始化一个Java类型,使该类型可以被正在运行的Java程序所使用.类型的生命周期如下图所示: 装载和连接必须在初始化之前就要完成. 类 ...

  4. 深入java虚拟机学习 -- 类的加载机制

    当看到"类的加载机制",肯定很多人都在想我平时也不接触啊,工作中无非就是写代码,不会了可以百度,至于类,jvm是怎么加载的我一点也不需要关心.在我刚开始工作的时候也觉得这些底层的内 ...

  5. 深入java虚拟机学习 -- 类的加载机制(续)

    昨晚写 深入java虚拟机学习 -- 类的加载机制 都到1点半了,由于第二天还要工作,没有将上篇文章中的demo讲解写出来,今天抽时间补上昨晚的例子讲解. 这里我先把昨天的两份代码贴过来,重新看下: ...

  6. 深入java虚拟机学习 -- 类的加载机制(三)

    类的初始化时机 在上篇文章中讲到了类的六种主动使用方式,反射是其中的一种(Class.forName("com.jack.test")),这里需要注意一点:当调用ClasLoade ...

  7. windows/tomcat 修改java虚拟机JVM以utf-8字符集加载class文件的两种方式

      1.情景展示 做了这么长时间的java开发,但是,你知道JVM是以怎样的编码加载.解析class文件的吗? 我们知道,通常情况下,我们会将java文件的字符集修改成utf-8,这样,理所当然地就认 ...

  8. Java提高篇——JVM加载class文件的原理机制

    在面试java工程师的时候,这道题经常被问到,故需特别注意. 1.JVM 简介 JVM 是我们Javaer 的最基本功底了,刚开始学Java 的时候,一般都是从“Hello World ”开始的,然后 ...

  9. java类到底是如何加载并初始化的?

    Java虚拟机如何把编译好的.class文件加载到虚拟机里面?加载之后如何初始化类?静态类变量和实例类变量的初始化过程是否相同,分别是如何初始化的呢?这篇文章就 是解决上面3个问题的. 若有不正之处, ...

随机推荐

  1. (笔记)Linux内核学习(一)之内核介绍

    内核与操作系统: 内核是操作系统的核心部分,包含了系统运行的核心过程,决定系统的性能,操作系统启动内核被装入到RAM中: 操作系统与底层硬件设备交互和为运行应用程序提供执行环境. Linux内核与微内 ...

  2. lua系列之 lua-cjson模块安装报错问题解决

    lua-cjson下载 下载地址 报错信息 [root@LeoDevops lua-cjson]# make cc -c -O3 -Wall -pedantic -DNDEBUG -I/usr/loc ...

  3. 设计模式-结构型模式,python组合模式

    设计模式上大的方向上分继承和组合,就是类模式和对象模式.此篇的组合模式非继承和组合概念中的组合.桥接 策略 代理 装饰者都用了组合,此组合非彼组合. 组合模式 组合模式(Composite Patte ...

  4. osx 10.11 一键制作U盘傻瓜工具最新版 无需任何命令

    osx 10.11 最新版U盘制作工具   无需任何命令   纯傻瓜式  !!!只要把app下载下来放在应用程序  鼠标点点就可以做了... 下载地址:http://diskmakerx.com/do ...

  5. C/C++判断传入的UTC时间是否在今天

    在项目中经常会显示一个时间,如果这个时间在今日内就显示为时分秒,否则显示为年月日. 这里先给出一个正确的版本: #include <iostream> #include <time. ...

  6. 如何将Unicode文本写到日志文件中

    有时为了定位问题,我们需要结合打印日志来处理.特别是较难复现的,一般都需要查看上下文日志才能找出可能存在的问题.考虑到程序要在不同语言的操作系统上运行,程序界面显示要支持Unicode,打印出来的日志 ...

  7. VS 开发必用插件

    C# outline --代码折叠 Indent Guides 虚线对齐 productivity power tools 功能集中在编辑.浏览以及其他常见的构造代码时会使用到的任务 Web Esse ...

  8. 使用SpringContextHolder获取bean实例

    public static IConstantFactory me(){ return SpringContextHolder.getBean(beanName:"constantFacto ...

  9. 基础知识——CentOS7操作系统的安装图文教程

    学习了很久的Linux操作系统,也看了不少的资料,对于操作系统的安装,相对来说都在不断的改进,安装的难度也在不断的降低,操作步骤也变得非常的简单了. 有很多CentOS系统的安装教程,但是比较不全面或 ...

  10. Web(一)

    Tomcat 服务器       B/S 浏览器/服务器       C/S 客户端/服务器  URI :大 广 /项目名                      URL: 小  http://lo ...