类加载过程

  • 加载(加载IO流文件,并存储类信息在方法区)->
  • 验证(格式验证,语义分析,操作验证)->
  • 准备(为类中的所有静态变量分配内存空间,并为其设置一个初始值)->
  • 解析(将常量池中的符号引用转为直接引用)->
  • 初始化(将一个类中所有被static关键字标识的代码统一执行一遍,如果执行的是静态变量,那么就会使用用户指定的值覆盖之前在准备阶段设置的初始值;如果执行的是static代码块,那么在初始化阶段,JVM就会执行static代码块中定义的所有操作)
  • static的代码(包括静态代码块)是在类加载的初始化阶段执行的。
  • final修饰的变量是在类加载的加载阶段执行的,比static靠前
  • 引自: https://www.cnblogs.com/xiaoxian1369/p/5498817.html

触发类加载的时机

  1. 当遇到字节码指令 new 、getstatic / put static (调用类的属性) 、invokeStatic(调用类的方法)时。
  2. 当反射调用类时。
  3. 引用一个小案例
  4. public class Book {public static void main(String[] args){staticFunction();}static Book book = new Book();static{System.out.println("书的静态代码块");}{System.out.println("书的普通代码块");}Book(){System.out.println("书的构造方法");System.out.println("price=" + price +",amount=" + amount);}public static void staticFunction(){System.out.println("书的静态方法");}int price = 110;static int amount = 112;
    }

    上面这个例子的输出结果是:

    
    书的普通代码块
    书的构造方法
    price=110,amount=0
    书的静态代码块
    书的静态方法

    下面我们一步步来分析一下代码的整个执行流程。

    在上面两个例子中,因为 main 方法所在类并没有多余的代码,我们都直接忽略了 main 方法所在类的初始化。

    但在这个例子中,main 方法所在类有许多代码,我们就并不能直接忽略了。

  5. 当 JVM 在准备阶段的时候,便会为类变量分配内存和进行初始化。此时,我们的 book 实例变量被初始化为 null,amount 变量被初始化为 0。
  6. 当进入初始化阶段后,因为 Book 方法是程序的入口,根据我们上面说到的类初始化的五种情况的第四种(当虚拟机启动时,用户需要指定一个要执行的主类(包含main()方法的那个类),虚拟机会先初始化这个主类)。所以JVM 会初始化 Book 类,即执行类构造器 。
  7. JVM 对 Book 类进行初始化首先是执行类构造器(按顺序收集类中所有静态代码块和类变量赋值语句就组成了类构造器 ),后执行对象的构造器(按顺序收集成员变量赋值和普通代码块,最后收集对象构造器,最终组成对象构造器 )。
  8. 对于 Book 类,其类构造方法()可以简单表示如下:

    static Book book = new Book();
    static
    {System.out.println("书的静态代码块");
    }
    static int amount = 112;

    于是首先执行static Book book = new Book();这一条语句,这条语句又触发了类的实例化。于是 JVM 执行对象构造器 ,收集后的对象构造器 代码:

    {System.out.println("书的普通代码块");
    }
    int price = 110;
    Book()
    {System.out.println("书的构造方法");System.out.println("price=" + price +", amount=" + amount);
    }

    于是此时 price 赋予 110 的值,输出:「书的普通代码块」、「书的构造方法」。而此时 price 为 110 的值,而 amount 的赋值语句并未执行,所以只有在准备阶段赋予的零值,所以之后输出「price=110,amount=0」。

    当类实例化完成之后,JVM 继续进行类构造器的初始化:

    static Book book = new Book();  //完成类实例化
    static
    {System.out.println("书的静态代码块");
    }
    static int amount = 112;

    即输出:「书的静态代码块」,之后对 amount 赋予 112 的值。

  9. 到这里,类的初始化已经完成,JVM 执行 main 方法的内容。
  10. public static void main(String[] args)
    {staticFunction();
    }

    即输出:「书的静态方法」。

    从上面几个例子可以看出,分析一个类的执行顺序大概可以按照如下步骤:

  11. 确定类变量的初始值。在类加载的准备阶段,JVM 会为类变量初始化零值,这时候类变量会有一个初始的零值。如果是被 final 修饰的类变量,则直接会被初始成用户想要的值。
  12. 初始化入口方法。当进入类加载的初始化阶段后,JVM 会寻找整个 main 方法入口,从而初始化 main 方法所在的整个类。当需要对一个类进行初始化时,会首先初始化类构造器(),之后初始化对象构造器()。
  13. 初始化类构造器。JVM 会按顺序收集类变量的赋值语句、静态代码块,最终组成类构造器由 JVM 执行。
  14. 初始化对象构造器。JVM 会按照收集成员变量的赋值语句、普通代码块,最后收集构造方法,将它们组成对象构造器,最终由 JVM 执行。
  15. 如果在初始化 main 方法所在类的时候遇到了其他类的初始化,那么就先加载对应的类,加载完成之后返回。如此反复循环,最终返回 main 方法所在类。

JVM深度学习系列之类加载问题分析(一)相关推荐

  1. JVM深度学习系列之实践经验(七)

    如何充分利用高性能服务器(比如:内存16G) 一般的思路是调大堆内存(12G) 但是同时会引起几个问题 年轻代GC和老年代GC的时间就会很长,严重的10多s,这样会导致系统不定时的卡顿(GC的stop ...

  2. JVM深度学习系列之内存实践(五)

    目标: 1 通过jvm参数的调整,优化GC 2. 通过内存分析工具定位导致内存泄漏或溢出的代码 通过jvm参数的调整,优化GC 表面现象: 1. 方法调用超时             2.方法TP99 ...

  3. JVM深度学习系列之内存使用细节(三)

    new 对象 检查类是否加载 在堆中分配空间 虚拟机调用init方法 对象的访问方式 句柄 (在堆中) 好处: 稳定,栈中保留句柄的指针,句柄指向实例数据,实例数据位置改变时(垃圾回收期间),栈中的指 ...

  4. 【深度学习系列】卷积神经网络CNN原理详解(一)——基本原理(1)

    上篇文章我们给出了用paddlepaddle来做手写数字识别的示例,并对网络结构进行到了调整,提高了识别的精度.有的同学表示不是很理解原理,为什么传统的机器学习算法,简单的神经网络(如多层感知机)都可 ...

  5. python系列文章(基础,应用,后端,运维,自动化测试,爬虫,数据分析,可视化,机器学习,深度学习系列内容)

    python基础教程 python基础系列教程--Python的安装与测试:python解释器.PyDev编辑器.pycharm编译器 python基础系列教程--Python库的安装与卸载 pyth ...

  6. 点云深度学习系列由浅入深之--SPLATNet: Sparse Lattice Networks for Point Cloud Processing

    点云深度学习系列由浅入深之--SPLATNet: Sparse Lattice Networks for Point Cloud Processing 0. SplatNet网络主要结构及模块 1. ...

  7. 腾讯深度学习系列——深度学习及并行化实现概述

    深度学习及并行化实现概述 摘要: 深度学习可以完成需要高度抽象特征的人工智能任务,如语音识别.图像识别和检索.自然语言理解等.深层模型是包含多个隐藏层的人工神经网络,多层非线性结构使其具备强大的特征表 ...

  8. 深度学习系列:深度学习在腾讯的平台化和应用实践

    深度学习系列:深度学习在腾讯的平台化和应用实践(一) 莫扎特 2015-01-04 6:05:13 大数据技术 评论(0) 深度学习是近年机器学习领域的重大突破,有着广泛的应用前景.随着Google公 ...

  9. 【深度学习系列】——神经网络的可视化解释

    这是深度学习系列的第三篇文章,欢迎关注原创公众号 [计算机视觉联盟],第一时间阅读我的原创!回复 [西瓜书手推笔记] 还可获取我的机器学习纯手推笔记! 深度学习系列 [深度学习系列]--深度学习简介 ...

最新文章

  1. java基础面试题:java中实现多态的机制是什么?
  2. 360脱壳-native函数还原笔记-2017-06-25
  3. selenium(2.4.0)中不能导出web drive 代码
  4. 支持html5特性的浏览器,HTML 5浏览器的支持情况
  5. 1-4 开发工具的选择
  6. 互联网平台“直播+”赋能研究报告
  7. rds for mysql的监控指标_支持的监控指标_云数据库 RDS_用户指南_MySQL用户指南_监控指标与告警_华为云...
  8. Nginx配置Thinkphp3.2.3配置,访问Nginx报 No input file specified. 的问题解决
  9. 【基本算法】概率算法
  10. 数字人体”视觉挑战赛-宫颈癌风险智能诊断
  11. VCL语法教程——1.变量及labels
  12. dns解析失败的处理办法
  13. 数据库(Mysql)的事物详解
  14. linux中时间转换date
  15. 容器化部署与传统部署的区别及优势
  16. 刀~~~~~~~~~~~~
  17. 三分钟了解多模光纤和单模光纤的区别-ielab
  18. 河北计算机四六级报名入口,四六级考试报名入口
  19. ubuntu 触摸板失灵解决
  20. nginx配置同一个端口转发多个项目

热门文章

  1. 半导体未来浪潮(深度好文)
  2. Vue首屏加载速度优化,我用这几个技巧提升80%以上
  3. OPPO手机路迷5G
  4. 数据库系统概念 第三章 SQL介绍
  5. 五四青年节54行代码向祖国告白
  6. P2P爆雷潮后的第100天,我们复盘了整个互金倒闭史
  7. 数字优惠券市场现状研究分析报告 -
  8. 紫光展锐春藤8908A NB-IoT芯片获得德国电信全球认证
  9. 航空公司客户价值分析python实战
  10. 第九部分 代理的使用(代理设置,代理池的搭建,用代理获取微信公众号文章)...