2019独角兽企业重金招聘Python工程师标准>>>

首先Throws(抛出)几个自己学习过程中一直疑惑的问题:

1、什么是类加载?什么时候进行类加载?

2、什么是类初始化?什么时候进行类初始化?

3、什么时候会为变量分配内存?

4、什么时候会为变量赋默认初值?什么时候会为变量赋程序设定的初值?

5、类加载器是什么?

6、如何编写一个自定义的类加载器?

首先,在代码编译后,就会生成JVM(Java虚拟机)能够识别的二进制字节流文件(*.class)。而JVM把Class文件中的类描述数据从文件加载到内存,并对数据进行校验、转换解析、初始化,使这些数据最终成为可以被JVM直接使用的Java类型,这个说来简单但实际复杂的过程叫做JVM的类加载机制

Class文件中的“类”从加载到JVM内存中,到卸载出内存过程有七个生命周期阶段。类加载机制包括了前五个阶段。

如下图所示:

其中,加载、验证、准备、初始化、卸载的开始顺序是确定的,注意,只是按顺序开始,进行与结束的顺序并不一定。解析阶段可能在初始化之后开始。

另外,类加载无需等到程序中“首次使用”的时候才开始,JVM预先加载某些类也是被允许的。(类加载的时机

一、类的加载

我们平常说的加载大多不是指的类加载机制,只是类加载机制中的第一步加载。在这个阶段,JVM主要完成三件事:

1、通过一个类的全限定名(包名与类名)来获取定义此类的二进制字节流(Class文件)。而获取的方式,可以通过jar包、war包、网络中获取、JSP文件生成等方式。

2、将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。这里只是转化了数据结构,并未合并数据。(方法区就是用来存放已被加载的类信息,常量,静态变量,编译后的代码的运行时内存区域)

3、在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。这个Class对象并没有规定是在Java堆内存中,它比较特殊,虽为对象,但存放在方法区中。

二、类的连接

类的加载过程后生成了类的java.lang.Class对象,接着会进入连接阶段,连接阶段负责将类的二进制数据合并入JRE(Java运行时环境)中。类的连接大致分三个阶段。

1、验证:验证被加载后的类是否有正确的结构,类数据是否会符合虚拟机的要求,确保不会危害虚拟机安全。

2、准备:为类的静态变量(static filed)在方法区分配内存,并赋默认初值(0值或null值)。如static int a = 100;

静态变量a就会在准备阶段被赋默认值0。

对于一般的成员变量是在类实例化时候,随对象一起分配在堆内存中。

另外,静态常量(static final filed)会在准备阶段赋程序设定的初值,如static final int a = 666;  静态常量a就会在准备阶段被直接赋值为666,对于静态变量,这个操作是在初始化阶段进行的。

3、解析:将类的二进制数据中的符号引用换为直接引用。

三、类的初始化

类初始化是类加载的最后一步,除了加载阶段,用户可以通过自定义的类加载器参与,其他阶段都完全由虚拟机主导和控制。到了初始化阶段才真正执行Java代码。

类的初始化的主要工作是为静态变量赋程序设定的初值。

如static int a = 100;在准备阶段,a被赋默认值0,在初始化阶段就会被赋值为100。

Java虚拟机规范中严格规定了有且只有五种情况必须对类进行初始化

1、使用new字节码指令创建类的实例,或者使用getstatic、putstatic读取或设置一个静态字段的值(放入常量池中的常量除外),或者调用一个静态方法的时候,对应类必须进行过初始化。

2、通过java.lang.reflect包的方法对类进行反射调用的时候,如果类没有进行过初始化,则要首先进行初始化。

3、当初始化一个类的时候,如果发现其父类没有进行过初始化,则首先触发父类初始化。

4、当虚拟机启动时,用户需要指定一个主类(包含main()方法的类),虚拟机会首先初始化这个类。

5、使用jdk1.7的动态语言支持时,如果一个java.lang.invoke.MethodHandle实例最后的解析结果REF_getStatic、REF_putStatic、RE_invokeStatic的方法句柄,并且这个方法句柄对应的类没有进行初始化,则需要先触发其初始化。

注意,虚拟机规范使用了“有且只有”这个词描述,这五种情况被称为“主动引用”,除了这五种情况,所有其他的类引用方式都不会触发类初始化,被称为“被动引用”。

被动引用的例子一:

通过子类引用父类的静态字段,对于父类属于“主动引用”的第一种情况,对于子类,没有符合“主动引用”的情况,故子类不会进行初始化。代码如下:

[java] view plain copy

  1. //父类
  2. public class SuperClass {
  3. //静态变量value
  4. public static int value = 666;
  5. //静态块,父类初始化时会调用
  6. static{
  7. System.out.println("父类初始化!");
  8. }
  9. }
  10. //子类
  11. public class SubClass extends SuperClass{
  12. //静态块,子类初始化时会调用
  13. static{
  14. System.out.println("子类初始化!");
  15. }
  16. }
  17. //主类、测试类
  18. public class NotInit {
  19. public static void main(String[] args){
  20. System.out.println(SubClass.value);
  21. }
  22. }

输出结果:

被动引用的例子之二:

通过数组来引用类,不会触发类的初始化,因为是数组new,而类没有被new,所以没有触发任何“主动引用”条款,属于“被动引用”。代码如下:

[java] view plain copy

  1. //父类
  2. public class SuperClass {
  3. //静态变量value
  4. public static int value = 666;
  5. //静态块,父类初始化时会调用
  6. static{
  7. System.out.println("父类初始化!");
  8. }
  9. }
  10. //主类、测试类
  11. public class NotInit {
  12. public static void main(String[] args){
  13. SuperClass[] test = new SuperClass[10];
  14. }
  15. }
 

没有任何结果输出!

被动引用的例子之三:

刚刚讲解时也提到,静态常量在编译阶段就会被存入调用类的常量池中,不会引用到定义常量的类,这是一个特例,需要特别记忆,不会触发类的初始化!

[java] view plain copy

  1. //常量类
  2. public class ConstClass {
  3. static{
  4. System.out.println("常量类初始化!");
  5. }
  6. public static final String HELLOWORLD = "hello world!";
  7. }
  8. //主类、测试类
  9. public class NotInit {
  10. public static void main(String[] args){
  11. System.out.println(ConstClass.HELLOWORLD);
  12. }
  13. }
 

转载于:https://my.oschina.net/u/2543341/blog/1504033

JVM类加载机制详解(一)JVM类加载过程相关推荐

  1. Java类加载机制详解【java面试题】

    Java类加载机制详解[java面试题] (1)问题分析: Class文件由类装载器装载后,在JVM中将形成一份描述Class结构的元信息对象,通过该元信息对象可以获知Class的结构信息:如构造函数 ...

  2. 【胖虎的逆向之路】01——动态加载和类加载机制详解

    胖虎的逆向之路 01--动态加载和类加载机制详解 一.前言 二.类的加载器 1. 双亲委派模式 2. Android 中的类加载机制 1)Android 基本类的预加载 2)Android类加载器层级 ...

  3. Java虚拟机中类加载机制详解

    Java虚拟机中类加载机制详解 1,什么是java类加载机制 **首先在java中,是通过编译来生成.class文件(可能在本地,或者网页下载),java的类加载机制就是 将这些.class文件加载到 ...

  4. 性能优化——Android热修复技术,类加载机制详解

    一.背景 热修复技术慢慢的成为Android开发必不可少的技术,也是成为一名高级程序员必不可少的技能之一.那么什么是热修复技术呢? 当app上线之后,发现了一个严重的bug,需要紧急修复,按照以往的惯 ...

  5. JVM类加载机制详解

    本文来详细说下JVM类加载机制 文章目录 概述 类加载器是什么 类加载的过程 加载 连接 初始化 类的主动引用和被动引用 主动引用 被动引用 三种类加载器 双亲委托机制 核心思想 源码分析 类的动态加 ...

  6. JVM类加载机制详解-20160812

    JVM类加载机制 一,类加载器体系     类加载器是沙箱的第一道防线,毕竟代码都是类加载器装入到JVM的.类加载体系通过使用不同的类加载器把类放 入不同的命名空间中,从而保护善意代码不受恶意代码的干 ...

  7. Java 类加载机制详解

    一.类加载器 类加载器(ClassLoader),顾名思义,即加载类的东西.在我们使用一个类之前,JVM需要先将该类的字节码文件(.class文件)从磁盘.网络或其他来源加载到内存中,并对字节码进行解 ...

  8. java里加载是什么意思_Java 类加载机制详解

    什么是 Java 类加载机制? Java 虚拟机一般使用 Java 类的流程为:首先将开发者编写的 Java 源代码(.java文件)编译成 Java 字节码(.class文件),然后类加载器会读取这 ...

  9. Java虚拟机:类加载机制详解

    版权声明:本文为博主原创文章,转载请注明出处,欢迎交流学习! 大家知道,我们的Java程序被编译器编译成class文件,在class文件中描述的各种信息,最终都需要加载到虚拟机内存才能运行和使用,那么 ...

最新文章

  1. ActivityMQ消息持久化到HANA数据库
  2. BCH虫洞项目有多安全以及WHC究竟能干什么?
  3. eclipse 运行MapReduce程序错误异常汇总(解决Map not fount)
  4. cuba 平台_CUBA 7的新功能
  5. 【渝粤教育】电大中专跨境电子商务理论与实务 (29)作业 题库
  6. 记:Ubuntu 14.04 安装32位库支持库失败
  7. ICMP协议与ping命令
  8. 模拟c语言的软件下载,c语言软件下载(C/C++模拟学习)
  9. SPSS实现数据归一化
  10. 计算机基础知识竞赛报道,学校举办第十四届计算机基础知识竞赛
  11. Android加固与脱壳分析
  12. Python数据分析工具Pandas——数值计算和统计基础
  13. python脚本迁移数据库_Django 数据库迁移脚本
  14. 小米 Redmi G Pro 游戏本锐龙版 评测
  15. 前端可以做的SEO搜索引擎优化(摘取)
  16. Qt数据库:(五)QSqlQueryModel
  17. 认证 (authentication) 和授权 (authorization) 的区别.md
  18. linux邮件thunderbird,在 Linux 中安装新版的Thunderbird 邮件客户端
  19. w10重装最简单的一个方法
  20. 海思3559A平台linux日志管理

热门文章

  1. 交通安全与智能控制专业学计算机吗,交通安全与智能控制专业排名好不好_主要课程及就业前景分析...
  2. android.process.media+sd,android P系统WRITE_MEDIA_STORAGE添加读写SD卡权限
  3. java 选中当前,Java开发网 - 请问如何获得SWT中List widget当前选中的项目
  4. 通达信版弘历软件指标_通达信弘历趋势王指标
  5. swift 拖动按钮_Swift下使用UICollectionView 实现长按拖拽功能
  6. ogg源端mysql添加trandata_OGG_GoldenGate日常维护(案例)
  7. java 前端页面传过来的值怎么防止篡改_杂谈!了解一些额外知识,让你的前端开发锦上添花...
  8. php 自旋锁,Linux内核自旋锁使用笔记
  9. java tika pdf转图片_使用tika将pdf转为html
  10. Django模型自定义查询管理器