1.ClassLoader(类加载器)

1.加载:查找并加载类的二进制数据

2.连接

—验证:确保被加载的类的正确性(防止不是通过java命令生成的class文件被加载)

—准备:为类的静态变量分配内存,并将其初始化为默认值(如int默认值为0)

—解析:把类中的符号引用转换为直接引用

3.初始化:为类的静态变量赋予正确的初始值(即代码中指定的值 例:public static int a = 2)

  • JAVA程序对类的使用方式可以分为两种

  —主动使用(六种)

  —被动使用(除了主动使用的六种方法,其余的都属于被动使用)

  • 所有的Java虚拟机实现必须在每个类或接口被Java程序“首次主动使用”时才初始化
  • 主动使用

  —创建类的实例

  —访问某个类或接口的静态变量,或者对静态变量赋值(int b = Test.a)

  —调用类的静态方法

  —反射,Class.forName("Test");

  —初始化了一个类的子类

  —Java虚拟机启动的时被表明为启动的类  进入cmd使用Java命令   com.xyw.Test(包含main方法)

类的加载:

  类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构

加载.class的方式

—从本地系统中直接加载

—通过网络下载.class文件

—从zip,jar等归档文件中加载.class文件

—从专有数据库中提取.class文件

—将Java源文件动态编译为.class文件

类的加载的最终产品是位于堆区中的Class对象

Class对象封装了类在方法区内的数据结构,并且向Java程序员提供了访问方法区内的数据结构的接口(即反射 Reflect)

有两种类型的类加载器

—Java虚拟机自带的加载器

根类加载器(Bootstrap) C++编写,程序员无法在java代码中获得该类

扩展类加载器(Extension) java实现

系统类加载器(System) java实现

—用户自定义的类加载器

java.lang.ClassLoader的子类(自定义加载器必须extends这个抽象类)

用户可以定制类的加载方式

类的验证:

类加载器并不需要等到某个类被“首次主动使用”的时再加载它

JVM规范允许类加载器在预料的某个类将要被使用的时候加载它,如果在预先加载的过程中遇到了.class文件缺失或存在错误,类加载器必须在程序首次主动使用该类的时才报告错误(LinkageError错误)

如果这个类一直没有被程序主动使用,那么类加载器就不会报告错误

类被加载后,就进入连接阶段,连接就是将已经读入内存的类的二进制数据合并到虚拟机的运行时环境中去

类的验证的内容:

1.类文件的结构检查 :确保类文件遵从java类文件的格式

2.语义检查 :确保类本身符合java语言的语法规定,比如验证final类型的类没有子类,已经final方法没有被覆盖

3.字节码验证:确保字节码流可以被JVM安全的执行,字节码代表java方法(包括静态方法和实例方法)

4.二进制兼容性的验证:确保相互引用的类之间的协调一致

类的准备:

在准备阶段,java虚拟机为类的静态变量分配内存,并设置默认的初始值,例如将为int类型的静态变量分配4个字节的内存空间,初始值为0,为long类型的静态变量分配8个字节的内存空间,默认值为0

在解析阶段,java虚拟机会把类的二进制数据中的符号引用替换为直接引用,在一个类中的方法调用另一个类的方法叫做符号引用,解析阶段,Java虚拟机会把这个符号引用替换为一个指针,指向该类的方法区内的内存位置,这个就是直接引用

在初始化阶段,Java虚拟机执行类的初始化语句,为类的静态变量赋予初始值,在程序中,静态变量初始化有两种途径1.在静态变量的声明处进行初始化2.在静态代码块中进行初始化

静态变量的声明语句,以及静态太马克都被看做类的初始化语句,Java虚拟机会按照初始化语句在类文件中的先后顺序来依次执行

类的初始化步骤:

1.假如这个类还没有被加载和连接,那就先进行加载和连接

2.假如类存在直接的弗雷,并且这个父类还没有被初始化,那就先初始化直接的父类

3.假如类中存在初始化语句,那就依次执行这些初始化语句

当java虚拟机初始化一个类时,要求它所有的父类都已经初始化,但是这条规则并不使用于接口

1.在初始化一个类时,并不会先初始化它所实现的接口

2,在初始化一个接口时,并不会先初始化它的父接口

因此,一个父接口并不会因为它的子接口或者实现类的初始化而初始化,只有当程序首次使用特定接口的静态变量时,才会导致该接口的初始化

程序中对子类的“主动使用”会导致父类的初始化,但对父类的“主动使用”并不会导致子类的初始化

只有当程序访问的静态变量或静态方法确实在当前类或当前接口中定义时,才可以认为是对类或接口的主动使用(如果只访问一个类的父类的静态变量,这样只初始化了父类,当前类没有被“主动使用”)

类的初始化时机

调用ClassLoader类的loadClass方法加载一个类,并不是对类的主动使用,不会导致类的初始化

类加载器:

类加载器用来把类加载到Java虚拟机中,从jdk1.2开始,类的加载过程采用父亲委托机制,这种机制更好的保证java平台的安全,在此委托机制中,除了java虚拟机自带的跟加载器以外,其余的类加载器都有且只有一个父类加载器,当java程序请求加载loader1加载一个类的时候,loader1首先委托自己的父加载器去加载该类,如果父加载器能够加载,则由父加载器加载,否则才由loader1加载器加载,都不能加载则抛出异常

根加载器:没有父加载器,负责加载虚拟机的核心类库,根类加载器实现依赖于低层次操作系统,属于虚拟机的实现的一部分,并没有继承ClassLoader类

扩展类加载器:它的父加载器为根类加载器(父加载器不代表父类)

系统类加载器:它的父加载器为扩展类加载器,它从环境变量classpath或者系统属性java.class.path所指定的目录中加载类,它是用户自定义的类加载器的默认父加载器

父子加载器并非继承关系,也就是说子加载器不一定要继承父加载器,是包装关系

除了以上虚拟机自带的加载器以外,用户还可以定制自己的类加载器(user-defined Class Loader).java提供了抽象类java.lang.ClassLoader,用户自定义的类加载器应该继承ClassLoader类

在父亲委托机制当中,各个加载器按照父子关系形成了树形结构,除了跟类加载器以外,其余的加载器都有且只有一个父加载器

若有一个类加载器能成功加载一个类,那么这个类加载器被称为定义类加载器,所有能成功返回Class对象的引用的类加载器(包括定义类加载器)都被称为初始类加载器

当生成一个自定义的类加载器的实例时,如果没有指定它的父加载器,那么系统类加载器就好自动成为该类的父加载器

运行时包

由同一个加载器加载的属于相同的类组成了运行时包,决定两个类是不是属于同一个运行时包,不仅要看它们的包名是否相同,还要看定义类加载器是否相同,只有属于同一运行时包的类才能相互访问包可见的类和类成员。这样的限制避免用户自定义的类冒充核心类库的方法,去访问核心类的包可见成员。假设用户自己定义一个类java.lang.Spy,并由用户自定义的类加载器加载,由于和核心类库java.lang.*由不同的加载器加载,他们不属于运行时包

要创建用户自己的类加载器,只需扩展java.lang.ClassLoader类,然后覆盖它的findClass(String name)方法即可,该方法根据参数指定的类的名字,返回对应的Class对象的引用

同一个命名空间内的类是相互可见的

子加载器的命名空间包含所有父加载器的命名空间,因此由子加载器加载的类能看见父加载器加载的类,例如系统类加载器加载的类能看见根类加载器加载的类

由父加载器加载的类不能看见子加载器加载的类

如果两个加载器之间没有直接或间接的父子关系,那么他们各自加载的类相互不可见

java JVM的更多相关文章

  1. Java (JVM) Memory Model – Memory Management in Java

    原文地址:http://www.journaldev.com/2856/java-jvm-memory-model-memory-management-in-java Understanding JV ...

  2. JAVA JVM虚拟机选项:Xms Xmx PermSize MaxPermSize 区别

    Xms : 是指设定程序启动时占用内存大小.一般该值设置大的会使程序启动快,但是可能会使本机暂时变慢. Xmx : 是指设定程序运行期间最大可占用的内存大小,如果程序运行需要占用更多的内存,超出这个 ...

  3. Java JVM、JNI、Native Function Interface、Create New Process Native Function API Analysis

    目录 . JAVA JVM . Java JNI: Java Native Interface . Java Create New Process Native Function API Analys ...

  4. Java多线程学习笔记——从Java JVM对多线程数据同步的一些理解

       我们知道在多线程编程中,我们很大的一部分内容是为了解决线程间的资源同步问题和线程间共同协作解决问题.线程间的同步,通俗我们理解为僧多粥少,在粥有限情况下,我们怎么去防止大家有秩序的喝到粥,不至于 ...

  5. Java JVM 多态(动态绑定)

    Java JVM 多态(动态绑定) @author ixenos 摘要:绑定.动态绑定实现多态.多态的缺陷.纯继承与扩展接口.向下转型与RTTI 绑定 将一个方法的调用和一个方法的主体关联起来,称作( ...

  6. Java JVM 内存泄漏--全解析和处理办法 [ 转载 ]

    Java JVM 内存泄露——全解析和处理办法 [转载]   @author 小筐子 @address http://www.jianshu.com/p/bf159a9c391a         JA ...

  7. Java JVM使用哪种编码格式

    Java JVM使用哪种编码格式 A ASCII characters  B Unicode characters C Cp1252 D UTF-8 E GBK F GBK2312 答案:B   在J ...

  8. Apache Curator is a Java/JVM client library for Apache ZooKeeper

    http://curator.apache.org/index.html Welcome to Apache Curator What is Curator? Curator n ˈkyoor͝ˌāt ...

  9. Java JVM监控工具JConsole简介

    Java JVM监控工具JConsole简介 jconsole命令 功能:打开java监视管理控制台 方法: jconsole [选项1] [选项2] …… [选项n] 常用选项: -help     ...

  10. 查看Java JVM参数配置信息命令

    查看Java JVM参数配置信息命令 java -XX:+PrintCommandLineFlags jvm运行时状态的参数,可以很快找出问题所在.现在把几个命令记录一下:1. jstat这个命令对于 ...

随机推荐

  1. js设计模式总结-代理模式

    代理模式 解决哪一类问题 从字面意思上理解,代理模式解决对一个对象的直接访问,这种直接访问可能是"不方便"的,所谓"不方便"可能是直接访问成本比较大(在前端领域 ...

  2. JFinal 国际化

    要支持国际化,需要在容器初始化的时候配置一个处理国际化的全局拦截器.比如可以使用 com.jfinal.i18n.I18nInterceptor 配置拦截器: public class MppConf ...

  3. 【开园 and 计划】

    开园 啊啊啊啊啊啊啊啊,郁闷啊,头一回写博客,一刻钟前保存的草稿为何荡然无存??? 那少废话直击要点:今日乃我开园之日,开园为了改变.为了学习.为了积累. 计划 最长为时 3月,截止到 2016年9月 ...

  4. 上传文件fileupload

    文件上传: 需要使用控件-fileupload 1.如何判断是否选中文件? FileUpload.FileName -  选中文件的文件名,如果长度不大于0,那么说明没选中任何文件 js - f.va ...

  5. I2C总线(异步)

    起始位与停止位的定义: 起始信号:当SCL为高期间,SDA由高到低的跳变:启动信号是一种电平跳变时序信号,而不是一个电平信号. 停止信号:当SCL为高期间,SDA由低到高的跳变:停止信号也是一种电平跳 ...

  6. mybatis入门_一对多,多对多映射以及整合spring框架

    一.一对多映射. 1.1 一对多映射之根据多的一方关联查询一的一方 示例:查询出具体的订单信息,同时也查询出来订单的用户信息. 引入的订单表如下所示: 框选出来的为具体的外键. 订单的Pojo类如下所 ...

  7. 知乎背景图 canvas 效果

    思路分析: 1.创造一块画布, 2.在画布内随机产生一些小球,小球位置,半径,颜射,大小,速度等都可以随机产生, 3.定义画小球函数与小球移动函数, 4.将每一个小球圆心都与其它小球链接, 5判断每一 ...

  8. MySQL DCL 整理

    DCL(Data Control Language)数据库控制语言  授权,角色控制等GRANT 授权REVOKE 取消授权

  9. MySQL数据库常用命令

    1.连接mysql数据库:mysql -u用户名 -p密码; 2.创建数据库:create database 数据库名称; 3.删除数据库:drop database 数据库名称; 4.使用数据库:u ...

  10. [Java] 特殊正则-替换字符串

    public class Test { public static void main(String[] args) { String str = "2412rhttp://192.168. ...