深入JVM整理文档

所需积分/C币:10 2017-04-18 18:43:49 2.1MB PDF

深入JVM整理文档
Java class文件格式 Java应用编程接囗( Java aPi) Java虚拟机 Java面向网络的核心就是Java虚拟机,它支持Java面向网络体系结构三大支 柱的所有方面:平台无关性,完全性和网络移动性。 12、Java程序的执行过程 类装载器 程序cass文件 ClassLoader Java ap的cass文件 字节码 执行引擎 本地方法调用 主机操作系统 Java技术的核心就是Java虚拟机,因为所有的Java程序都在虚拟机上 运行。Java程序的运行需要Java虚拟机、 Java api和 Java class文件的配合。 Java虚拟机实例负责运行一个Java程序。当启动一个Java程序时,一个虚拟 机实例就诞生了。当程序结束,这个虚拟机实例也就消亡。 13、加载 class文件的方式 1)从本地系统中直接加载 2)通过网络下载 class文件( URLClassloader) 3)从zip,jar等归档文件中加载dass文件 4)从专有数据库中提取cass文件 5)将Java源文件动态编译为. class文件 14、JVM内部结构 clas文件 类川载器 子系统 内存空间 垃圾 方法区a维Jaa钱 本鸠 收集器 方法栈 地址 和指备 PC青存器 执行引擎 本地方法1 接口 本地方法库 14.1、JVM与程序的生命周期 在如下几种情况下,Java虚拟机将结束生命周期 1)执行了 System. exit0方法 java. lang objec java. langSystem public static void exit(int status) Terminates the currently running Java Virtual Machine. The argument serves as a status code; by convention, a nonzero status code indicates abnormal termination This method calls the exit method in class runtime. this method never returns normall 2)程序正常执行结束 3)程序在执行过程中遇到了异常或错误而异常终止 4)由于操作系统出现错误而导致Java虚拟机进程终止 14.1、类装载器( Classloader) 142、类装载器的装载、链接与初始化 类装载器子系统除了要定位和导入二进制cass文件外,还必须负责验 证被导入类的正确性,为类变量分配并初始化内存,以及帮助解析符号引用。 这些动作必须严格按以下顺序进行 (1)装载——查找并装载类型的二进制数据 (2)连接指向验证、准备、以及解析(可选) 验证∶确保被导入类型的正确性(java可以自定义安全策略等) 准备:为类变量分配内存,并将其初始化为默认值 解析:把类型中的符号引用转换为直接引用 (3)初始化——把类变量初始化为正确初始值 连接 加 验证 准备 解析 LoadIng Verification Preparaton Resolusion 载 使用 初始化 UnLoading Using Initializaion 图1.3.2 143、有两种类型的类加载器(父委托机制) 启动类装载器 C++编写 Bootstrap ClassLoader Java虚拟机自带的加载器 扩展类装载器 Extension ClassLoader Java实现 应用程序类装载器 Application ClassLoader 用户自定义的类加载器 用户自定义类装载器 User Classloader 图1.33 1)Java虚拟机自带的加载器 ·根类加载器〔 Bootstrap【C++编写,无法在Java代码获取】) ·扩展类加载器( Extension【ava代码实现】) ·系统类加载器( System【 AppClassloader】) 2)用户自定义的类加载器 java. lang ClassLoader的子类 用户可以定制类的加载方式 类的父委托机制 父亲委托机制的优点是能够提高软件系统的安全性。因为在此机制下,用户自定义 的类加载器不可能加载应该由父加载器加载的可靠类,从而防止不可靠甚至恶意的代码 代替由父加载器加载的可靠代码。例如, java.lang Object类总是由根类加载器加载,其 他任何用户自定义的类加载器都不可能加载含有恶意代码的 java. lang Object类 命名空间 每个类加载器都有自己的命名空间,命名空间由该加载器及所有父加载器所加载 的类组成。在同一个命名空间中,不会出现类的完整名字(包括类的包名)相同的两 个类:在不同的命名空间中,有可能会出现类的完整名字(包括类的包名)相同的两 个类 运行时包 由同一类加载器加载的属于相同包的类组成了运行时包。决定两个类是不是属于 同一个运行时包,不仅要看它们的包名是否相同,还要看定义类加载器是否相同。只 有属于同一运行时包的类才能互相访问包可见(即默认访问级别)的类和类成员。这 样的限制能避免用户自定义的类冒充核心类库的类,去访问核心类库的包可见成员。 假设用户自己定义了一个类 java. lang.Spy,并由用户自定义的类加载器加载,由于 java. lang Spy和核心类库 java. lang.*由不同的加载器加载,它们属于不同的运行时包, 所以 java. lang Spy不能访问核心类库 java. lang包中的包可见成员。 创建用户自定义加载器(N) 要创建用户自己的类加载器,只需要扩展 java. lang ClassLoader类,然后覆盖它的 findClass(String name)方法即可,该方法根据参数指定的类的名字,返回对应的 Class 对象的引用 类的卸载 由Java虚拟机自带的类加载器所加载的类,在虚拟机的生命周期中,始终不会被 卸载。前面已经介绍过,Java虚拟机自带的类加载器包括根类加载器、扩展类加载器 和系统类加载器。Java虚拟机本身会始终引用这些类加载器,而这些类加载器则会始 终引用它们所加载的类的Cass对象,因此这些 Class对象始终是可触及的 由用户自定义的类加载器所加载的类是可以被卸载的 144、类的加载器与类 类的加载指的是将类的 class文件中的二进制数据读入到内存中,将其放 在运行时数据区的方法区内,然后在堆区创建一个 java. lang Class对象,用来 封装类在方法区内的数据结构,并且向Java程序员提供了访问方法区内的数据 结构的接口。 堆 方法区 调用cas对象 Java程序 描述Test类的clas对象 Test类的数据结构 比如 newnstanee0 图13.4 类加载器虽然只用于实现类的加载动作,但它在Java程序中起到的作用却 远远不限于类加载阶段。对于任意一个类,都需要由加载它的类加载器和这个 类本身一同确立其在Java虚拟中的唯一性。说通俗一些,比较两个类是否“相 等”,只有在两个类是由同一个类加载器的前提之下才有意义,否则,即使这 两个类来源于同一个 class文件,只要加载它的类加载器不同,那这两个类必 定不相等。这里所指的“相等”包括代表类的Cass对象的equa方法、 isAssignable FromO、 inStance0方法及 Instance关键字返回的结果。 1)类加载器并不需要等到某个类被“首次主动使用”时再加载它。意思就是 在使用之前类加载器已经加载了,只是等到我们进行main函数时才提示 我们(比如类没有找到什么的)。 2)八M规范允许类加载器在预料某个类将要被使用时就预先加载它,如果在 预先加载的过程中遇到了cass文件缺失或存在错误,类加载器必须在程序 首次主动使用该类时才报告错误( Linkage Error错误)。 java. lang Class Linkage Error java. lang object java. lang Throwable java. lang Error java. lang Linkage Error 3)如果这个类一直没有被程序主动使用,那么类加载器就不会报告错误。 4)类被加载后,就进入连接阶段。连接就是将已经读入到內存的类的二进制 数据合并到虚拟机的运行时环境中去。 14.5、类的验证( class文件检查器 类被加载后,就进入连接阶段。连接就是将已经读入到内存的类的二进制 数据合并到虚拟机的运行时环境中去。 1)类文件的结构检查(保证正确的内部结构):是通过 class文件检查器保 证裝载的cass文件内容有正确的内部结构,并且这些 class文件互相间协 调一致。 Class文件检査器实现的安全目标之一就是程序的健壮性。如果某 个有漏洞的编译器,产生了一个 class文件,而这个 class文件中包含了 个方法,这个方法的字节码中含有一条跳转到方法之外的指令,那么, 旦这个方法被调用,它将导致虚拟机的崩溃,所以,处于对健壮性的考虑, 由虚拟初检验它装载的字节码的完整性非常重要。 第一趟扫描的目的就是保证这个字节序列正确的定义了一个cass。它 必须遵从Java的 class文件的固定格式,这样它才能被编译成在方法区中 的(基于实现的)内部数据结构 2)语义检查(比如字符串必须符合特定的语法规范):检查器对每个组成都 分进行检査的目的之一,是为了确认每个方法描述符合特定的语法规则 格式正确的字符串。 3)字节码验证〔确保字节码流可以被Java虛拟机安全地执行):字节码流代 表Java方法(包括静态方法和实例方法),它是由操作码单字节指令的组 成序列,每一个操作数后都跟着一个或者多个操作数。 4)符号引用的验证(必须检查被检测的cass文件以外的其他类):可能引 入装载的类,大多数Java虚拟机的实现采用延迟加载类的策略,就是用到 了才加载。将符号引用替换为直接引用,就是一个类指向类,字段或者方 法的指针或者偏移量。 5)二进制兼容性的验证(确保相互引用之间协调一致):比如引用的jar包中 的类之间方法引用,在Java虚拟机在验证类中的方法,检査在方法区内是 否存在这个方法,如果不存在就抛出 NoSuchMethod error错误。或者版 本不兼容,比如有时低版本的引用到高版本可以会出错,但是Java的版本 都是向上兼容的,在高版本引用低版本不会出现这种错误。 146、类的准备 Java虛拟机为类的静态变量分配内存,并设计默认的初始值。比如int 类型的类型静态变量a分配4个字节的内存空间,并赋予默认值为0(都知道 int类型的默认值吧)。 14.7、类的解析 Java虚拟机会把类的二进制数据中的符号引用替换为直接引用,比如在 一个类A中引用到类B的方法,在类A的二进制数据中,包含了这个方法的符 号引用,由方法的全名和相关的描述组成。在此阶段会把这个符号引用替换成 一个指针,该指针指向类B中的方法在方法区的内存位置。 14.8、类的初始化 Java虚拟机执行初始化语句是有先后顺序依次执行,而且是在加载和链 接完成后(如果没有加载链接那就进行加载链接),再为类的静态变量赋值赋 予初始值。在静态变量的声明中岀迸行初始化(就是inta=1;初始化值就是 1),在静态代码块中进行初始化(inta;而赋值是在 static方法里面进行初始 化),如果没初始化的变量将保持默认值。 (1)假如这个类还没有被加载和连接,那就先进行加载和连接。 (2)假如类存在直接的父类,并且这个父类还没有被初始化,那就先初始化直接 的父类。 (3)假如类中存在初始化语句,那就依次执行这些初始化语句。 15、类的使用方式可分为两种 主动使用 被动使用 ·所有的Java虛拟机实现必须在每个类或接口被Java程序“首次主动使用 时才初始化它们。 主动使用(六种) 1)创建类的实例(如new一个对象) 2)访问某个类或接口的静态变量,或者对该静态变量赋值(类变量) 3)调用类的静态方法(类静态方法) 4)反射(如 Class forname(" com.shengsiyuan Test”)) 5)初始化一个类的子类 6)Java虚拟机启动时被标明为启动类的类( Javatest) 除了以上六种情况,其他使用Java类的方式都被看作是对类的被看作是对类 的被动使用,都不会导致类的初始化。

...展开详情
试读 25P 深入JVM整理文档

评论 下载该资源后可以进行评论 1

撸码一点半 不值得啊,不要下载,太简洁呢。
2019-01-17
回复
img
陈郑游
  • GitHub

    绑定GitHub第三方账户获取
  • 签到新秀

    累计签到获取,不积跬步,无以至千里,继续坚持!

关注 私信 TA的资源

上传资源赚积分,得勋章
    最新推荐
    深入JVM整理文档 10积分/C币 立即下载
    1/25
    深入JVM整理文档第1页
    深入JVM整理文档第2页
    深入JVM整理文档第3页
    深入JVM整理文档第4页
    深入JVM整理文档第5页
    深入JVM整理文档第6页
    深入JVM整理文档第7页
    深入JVM整理文档第8页

    试读已结束,剩余17页未读...

    10积分/C币 立即下载 >