array(2) { ["docs"]=> array(10) { [0]=> array(10) { ["id"]=> string(3) "428" ["text"]=> string(77) "Visual Studio 2017 单独启动MSDN帮助(Microsoft Help Viewer)的方法" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(8) "DonetRen" ["tagsname"]=> string(55) "Visual Studio 2017|MSDN帮助|C#程序|.NET|Help Viewer" ["tagsid"]=> string(23) "[401,402,403,"300",404]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400964" ["_id"]=> string(3) "428" } [1]=> array(10) { ["id"]=> string(3) "427" ["text"]=> string(42) "npm -v;报错 cannot find module "wrapp"" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "zzty" ["tagsname"]=> string(50) "node.js|npm|cannot find module "wrapp“|node" ["tagsid"]=> string(19) "[398,"239",399,400]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400760" ["_id"]=> string(3) "427" } [2]=> array(10) { ["id"]=> string(3) "426" ["text"]=> string(54) "说说css中pt、px、em、rem都扮演了什么角色" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(12) "zhengqiaoyin" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400640" ["_id"]=> string(3) "426" } [3]=> array(10) { ["id"]=> string(3) "425" ["text"]=> string(83) "深入学习JS执行--创建执行上下文(变量对象,作用域链,this)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "Ry-yuan" ["tagsname"]=> string(33) "Javascript|Javascript执行过程" ["tagsid"]=> string(13) "["169","191"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511399901" ["_id"]=> string(3) "425" } [4]=> array(10) { ["id"]=> string(3) "424" ["text"]=> string(30) "C# 排序技术研究与对比" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "vveiliang" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(8) ".Net Dev" ["catesid"]=> string(5) "[199]" ["createtime"]=> string(10) "1511399150" ["_id"]=> string(3) "424" } [5]=> array(10) { ["id"]=> string(3) "423" ["text"]=> string(72) "【算法】小白的算法笔记:快速排序算法的编码和优化" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "penghuwan" ["tagsname"]=> string(6) "算法" ["tagsid"]=> string(7) "["344"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511398109" ["_id"]=> string(3) "423" } [6]=> array(10) { ["id"]=> string(3) "422" ["text"]=> string(64) "JavaScript数据可视化编程学习(二)Flotr2,雷达图" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "chengxs" ["tagsname"]=> string(28) "数据可视化|前端学习" ["tagsid"]=> string(9) "[396,397]" ["catesname"]=> string(18) "前端基本知识" ["catesid"]=> string(5) "[198]" ["createtime"]=> string(10) "1511397800" ["_id"]=> string(3) "422" } [7]=> array(10) { ["id"]=> string(3) "421" ["text"]=> string(36) "C#表达式目录树(Expression)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "wwym" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(4) ".NET" ["catesid"]=> string(7) "["119"]" ["createtime"]=> string(10) "1511397474" ["_id"]=> string(3) "421" } [8]=> array(10) { ["id"]=> string(3) "420" ["text"]=> string(47) "数据结构 队列_队列实例:事件处理" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "idreamo" ["tagsname"]=> string(40) "C语言|数据结构|队列|事件处理" ["tagsid"]=> string(23) "["246","247","248",395]" ["catesname"]=> string(12) "数据结构" ["catesid"]=> string(7) "["133"]" ["createtime"]=> string(10) "1511397279" ["_id"]=> string(3) "420" } [9]=> array(10) { ["id"]=> string(3) "419" ["text"]=> string(47) "久等了,博客园官方Android客户端发布" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(3) "cmt" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511396549" ["_id"]=> string(3) "419" } } ["count"]=> int(200) } 222 《Java高并发编程详解-多线程架构与设计》Java Classloader - 爱码网
thewindkee

摘自《Java高并发编程详解-多线程架构与设计》第九章 p144-p157
Java语言规范

重点:

  1. 连接-准备阶段为静态变量赋初值,初始化阶段为静态变量赋代码值
  2. 引起初始化阶段的6种情况(主动引用),静态变量/方法,new,反射,子类引起父类。
  3. 被动引用,如静态常量。其值copy到被引用的类。
  4. 类加载的三个阶段
  5. 静态代码块可以对后面的静态变量赋值,但不能访问。
  6. clinit线程安全

1.类加载的三个过程-简述

  1. 加载阶段
    查找并加载class文件
    loadClass from somewhere -> getClassBytes and defineClass->return Class
    常见异常:ClassNotFoundException,NoClassDefFoundError

  2. 连接阶段
    a. 验证
    确保类文件正确性。如class版本,魔数 CAFEBABE
    b. 准备-赋初始值
    为类的静态变量 分配内存,初始化【默认值】。
    c. 解析
    将类中符号引用转为直接引用。
    如引用了其他类, 则其他类先要经历类的所有加载过程。

  3. 初始化阶段 <clinit>()-赋代码值
    class initailze为类的静态变量赋予正确的值(代码编写时指定的值)

2. 类的主动使用和被动使用

JVM虚拟机规定,类和接口被java程序首次主动使用才会对其进行初始化。

主动使用的场景-new,反射,使用静态部分,子导致父初始化

  1. new
  2. 访问类的静态变量
  3. 访问类的静态方法
  4. 对类进行反射操作 。 如 Class.forName(“xx”); 参考java.sql.driver初始化驱动时调用DriverManager注册driver。ps:ClassLoader.loadClass不会触发【连接-初始化阶段】,只会触发【加载阶段】。
  5. 初始化子类导致父类的初始化
    同理, 调用子类的静态变量会导致父类的初始化。

在这里插入图片描述
6. 启动类:执行main锁在的类会导致该类的初始化

在这里插入图片描述

除了上述6种,其他的都为被动使用,不会导致类的【加载】和【初始化】。

在这里插入图片描述

被动使用

  1. 引用类的静态常量
    ps:静态常量会在编译期间被计算出来copy到其他类,可使用javap查看class文件

  2. 声明数组

3. 类的加载过程详解

例子
在这里插入图片描述

在这里插入图片描述

3.1 类的加载阶段

关键:1.得到class对应的二进制流(不限方式)2.defineClass

类的加载最终产物是堆内存中的class对象,对于同一个classLoader,不管加载多少次,对应到堆内存中的class是同一个(from cache)。
所以可以使用不同的classLoader加载同名的不同类

虚拟机规范规定类的加载是通过全限定名(包名+类名)来获取二进制数据流。
调用loadClass->findClass->getClassBytes+defineClass

常见的是class二进制文件形式,但可以是以下:

  1. 运行时动态生成,如ASM ,jdk动态代理,CGLIB
  2. 网络获取
  3. 读取zip获得类的二进制字节流,如war,jar。
    war,jar使用的是和zip一样的压缩算法。
  4. 将类的二进制文件储存在数据库的BLOB字段类型中。
  5. 运行时生成class文件,并动态加载,如Thrift/AVRO可以在运行时将schema文件生成对应的class文件再加载。

3.2 类的连接阶段

验证

文件格式:确保类文件正确性。如class版本,魔数 CAFEBABE,MD5比对(class末尾)等。

元数据:确保class符合jvm规范。语义验证。

字节码:…
符号引用:…

准备

为类的静态变量 分配内存,初始化默认值。
如 static int a = 10; 在【准备阶段】a是0而不是10。
如final static int b = 10; 注意,final static变量是【被动引用】,在编译期间即直接赋予了10;
在这里插入图片描述

在这里插入图片描述

解析

将类中符号引用转为直接引用。
在常量池中寻找类、接口、字段、方法的符号引用,将其替换成直接引用。
在这里插入图片描述

初始化

在这里插入图片描述
()保证顺序,对后面的静态变量只能赋值不能访问
在这里插入图片描述

类加载过程实例剖析

在这里插入图片描述

发布于2019年7月14日 20:24:54

分类:

技术点:

相关文章: