目录
1、Java 与 JVM 介绍 ................................................................................. 2
1.1、Java 体系结构包括四个独立的方面: .................................................. 2
1.2、Java 程序的执行过程 .......................................................................... 3
1.3、加载.class 文件的方式 ........................................................................ 3
1.4、JVM 内部结构 ............................................................................. 4
1.4.1、JVM 与程序的生命周期 ....................................................... 4
1.4.1、类装载器(ClassLoader) .................................................. 4
java.lang Class LinkageError ............................................................. 8
1.4.5、方法区 ............................................................................. 13
1.4.6、Java 堆 ............................................................................. 14
1.4.7、Java 栈 ............................................................................. 14
1.4.8、本地方法栈 ....................................................................... 14
1.4.9、PC 寄存器 ........................................................................ 14
1.4.10、本地方法 ........................................................................ 15
1.4.11、执行引擎 ........................................................................ 15
1.4.12 栈帧 ................................................................................. 15
1.4.13、本地栈帧 ........................................................................ 16
1.5、垃圾回收机制 GC ....................................................................... 16
老牌垃圾回收算法 (引用计算来回收垃圾 ) ................................. 17
标记-清除算法 ............................................................................. 17
标记-压缩算法 ............................................................................. 18
复制算法 ..................................................................................... 18
可触及性 ..................................................................................... 19
1.6、JVM 启动流程 ............................................................................ 20
1.7、内存模型 ................................................................................... 20
1.7、常用 JVM 配置参数 ..................................................................... 21
Trace 跟踪参数 ............................................................................ 22
堆的分配参数 .............................................................................. 22
栈大小分配 .................................................................................. 23
1.8、数据类型 ................................................................................... 24
1.9、字长考量 ................................................................................... 24
感谢信与参考文献 .................................................................................... 25
1、Java 与 JVM 介绍
JVM 是 Java Virtual Machine(Java 虚拟机)的缩写,JVM 是一种用
于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿
真模拟各种计算机功能来实现的。
Java 语言的一个非常重要的特点就是与平台的无关性。而使用 Java 虚
拟机是实现这一特点的关键。一般的高级语言如果要在不同的平台上运行,至
少需要编译成不同的目标代码。而引入 Java 语言虚拟机后,Java 语言在不同
平台上运行时不需要重新编译。Java 语言使用 Java 虚拟机屏蔽了与具体平台
相关的信息,使得 Java 语言编译程序只需生成在 Java 虚拟机上运行的目标代
码(字节码),就可以在多种平台上不加修改地运行。Java 虚拟机在执行字节
码时,把字节码解释成具体平台上的机器指令执行。这就是 Java 的能够“一次
编译,到处运行”的原因。
1.1、Java 体系结构包括四个独立的方面:
Java 程序设计语言
Java class 文件格式
Java 应用编程接口(Java API)
Java 虚拟机
Java 面向网络的核心就是 Java 虚拟机,它支持 Java 面向网络体系结构三大支
柱的所有方面:平台无关性,完全性和网络移动性。
1.2、Java 程序的执行过程
Java 技术的核心就是 Java 虚拟机,因为所有的 Java 程序都在虚拟机上
运行。Java 程序的运行需要 Java 虚拟机、Java API 和 Java Class 文件的配合。
Java 虚拟机实例负责运行一个 Java 程序。当启动一个 Java 程序时,一个虚拟
机实例就诞生了。当程序结束,这个虚拟机实例也就消亡。
1.3、加载.class 文件的方式
1) 从本地系统中直接加载
2) 通过网络下载.class 文件(URLClassLoader)
3) 从 zip, jar 等归档文件中加载.class 文件
4) 从专有数据库中提取.class 文件
5) 将 Java 源文件动态编译为.class 文件
1.4、JVM 内部结构
1.4.1、JVM 与程序的生命周期
• 在如下几种情况下, Java 虚拟机将结束生命周期
1) 执行了 System.exit()方法
java.lang.Object
java.lang.System
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 normally.
2) 程序正常执行结束
3) 程序在执行过程中遇到了异常或错误而异常终止
4) 由于操作系统出现错误而导致 Java 虚拟机进程终止
1.4.1、类装载器(ClassLoader)
1.4.2、类装载器的装载、链接与初始化
类装载器子系统除了要定位和导入二进制 class 文件外,还必须负责验
证被导入类的正确性,为类变量分配并初始化内存,以及帮助解析符号引用。
这些动作必须严格按以下顺序进行:
(1)装载——查找并装载类型的二进制数据
(2)连接——指向验证、准备、以及解析(可选)
● 验证:确保被导入类型的正确性(java 可以自定义安全策略等)
● 准备:为类变量分配内存,并将其初始化为默认值
● 解析:把类型中的符号引用转换为直接引用
(3)初始化——把类变量初始化为正确初始值
图 1.3.2
1.4.3、有两种类型的类加载器(父委托机制)
图 1.3.3
1) Java 虚拟机自带的加载器
• 根类加载器( Bootstrap【C++编写,无法在 Java 代码获取】)
• 扩展类加载器( Extension【Java 代码实现】)
• 系统类加载器( System【AppClassLoader】)
2) 用户自定义的类加载器
• java.lang.ClassLoader 的子类
• 用户可以定制类的加载方式
类的父委托机制
命名空间
运行时包
创建用户自定义加载器(N)
类的卸载
1.4.4、类的加载器与类
类的加载指的是将类的.class 文件中的二进制数据读入到内存中,将其放
在运行时数据区的方法区内,然后在堆区创建一个 java.lang.Class 对象,用来
封装类在方法区内的数据结构,并且向 Java 程序员提供了访问方法区内的数据
结构的接口。
图 1.3.4
类加载器虽然只用于实现类的加载动作,但它在 Java 程序中起到的作用却
远远不限于类加载阶段。对于任意一个类,都需要由加载它的类加载器和这个
类本身一同确立其在 Java 虚拟中的唯一性。说通俗一些,比较两个类是否“相
等”,只有在两个类是由同一个类加载器的前提之下才有意义,否则,即使这
两个类来源于同一个 class 文件,只要加载它的类加载器不同,那这两个类必
定不相等。这里所指的“相等”包括代表类的 Class 对象的 equal 方法、
isAssignableFrom()、isInstance()方法及 instance 关键字返回的结果。
1) 类加载器并不需要等到某个类被“首次主动使用”时再加载它。意思就是
在使用之前类加载器已经加载了,只是等到我们进行 main 函数时才提示
我们(比如类没有找到什么的)。
2) JVM 规范允许类加载器在预料某个类将要被使用时就预先加载它,如果在
预先加载的过程中遇到了.class 文件缺失或存在错误,类加载器必须在程序
首次主动使用该类时才报告错误( LinkageError 错误)。
java.lang
Class LinkageError
java.lang.Object
java.lang.Throwable
java.lang.Error
java.lang.LinkageError
3) 如果这个类一直没有被程序主动使用,那么类加载器就不会报告错误。
4) 类被加载后,就进入连接阶段。连接就是将已经读入到内存的类的二进制
数据合并到虚拟机的运行时环境中去。
1.4.5、类的验证(class 文件检查器)
类被加载后,就进入连接阶段。连接就是将已经读入到内存的类的二进制
数据合并到虚拟机的运行时环境中去。
1) 类文件的结构检查(保证正确的内部结构):是通过 class 文件检查器保
证装载的 class 文件内容有正确的内部结构,并且这些 class 文件互相间协
调一致。Class 文件检查器实现的安全目标之一就是程序的健壮性。如果某
个有漏洞的编译器,产生了一个 class 文件,而这个 class 文件中包含了一
个方法,这个方法的字节码中含有一条跳转到方法之外的指令,那么,一
旦这个方法被调用,它将导致虚拟机的崩溃,所以,处于对健壮性的考虑,
由虚拟机检验它装载的字节码的完整性非常重要。
第一趟扫描的目的就是保证这个字节序列正确的定义了一个 class。它
必须遵从 Java 的 class 文件的固定格式,这样它才能被编译成在方法区中
的(基于实现的)内部数据结构。
2) 语义检查(比如字符串必须符合特定的语法规范):检查器对每个组成都
分进行检查的目的之一,是为了确认每个方法描述符合特定的语法规则,
格式正确的字符串。
3) 字节码验证(确保字节码流可以被 Java 虚拟机安全地执行):字节码流代
表 Java 方法(包括静态方法和实例方法),它是由操作码单字节指令的组
成序列,每一个操作数后都跟着一个或者多个操作数。