1. JVM 位置
JDK>JRE>JVM ---->都与OS打交道
- JDK(java development kit0 是Java开发工具包,包括了Java运行环境JRE,Java 工具和 Java 基础类库。
- JRE(Java runtime environment)为java 的运行环境,包括JVM和Java核心类库。
- JVM(Java virtual machine)即Java虚拟机,整个java 实现跨平台的的最核心部分。所有java 程序首先被编译成java.class字节码文件,可以在JVM执行,JVM在执行字节码文件时,将其翻译成具体平台上的机器指令执行(一次编译,到处运行)(JVM执行程序大致过程:加载.class文件–>管理并分配内存—>执行垃圾收集)
2. JVM 体系结构
JVM调优一般指的是堆(大部分情况)和方法区
栈,本地方法栈,程序计数器:没有垃圾回收。
3. 类加载器
类加载器:加载class文件,分类(Java虚拟机角度:启动类加载器(Bootstrap ClassLoader),使用C++实现(HotSpot虚拟机中),是虚拟机自身一部分;其余所有类加载器)(开发者角度:高–>低):
- 虚拟机自带加载器
- 启动类(根)加载器:负责将Java_Home/lib下面的类库加载到内存中(比如rt.jar)。由于射击虚拟机本地实现细节,开发者无法直接获取启动类加载器的引用,不允许直接通过引用进行操作。
- 扩展类加载器:由Sun的ExtClassLoader实现。负责将Java_Home/lib/ext中的类库加载到内存。开发者可以直接使用。
- 应用程序加载器:由Sun的AppClassLoader实现。负责将系统类路径(CLASSPATH)中指定的类库加载到内存。可直接使用,由于这个类加载器是ClassLoader中的getSystemClassLoader()方法的返回值,也称系统加载器
类加载器的双亲委派机制:类加载器之间的层次关系(不是继承关系)。保证安全。
类加载器虽然只用于实现类的加载动作,但对于任意一个类,都需要由它的加载器和这个类本身共同确立其在Java虚拟机中的唯一性。即,JVM中两个类是否“相等”,必须是同一个类加载器加载,否则两个类来自同一Class文件,被不同加载器加载,也是不相等的(此处相等指类的Class对象的equals()方法,isInstance()方法的返回结果,instanceof关键字做对象所属关系判定等)
双亲委派工作流程:一个类加载器收到类加载的请求,首先不会自己区尝试加载这个类,而是把这个请求委派给父类加载器完成,每一个层次的加载器都是如此。这样,所有的类加载请求都会传给顶层的启动类加载器,只有当父加载器无法完成该加载请求(搜索范围内没有找到对应的类),子加载器才会尝试自己加载。
4 沙箱安全机制
沙箱是一个限制程序运行的环境。Java沙箱机制就是将Java代码限定在JVM特定的运行范围中,并且严格限制代码对本地系统资源访问,来保证对代码的有效隔离,放置对本地系统造成破坏。沙箱主要限制系统资源访问(CPU,内存,文件系统,网络)。不同级别沙箱访问限制不一样。
Java安全机制发展过程:
- JDK1.0(本地代码默认可信任,远程代码不受信依赖沙箱),不利于功能扩展
- 1.1,增加安全策略,允许用户指定代码对本地资源的访问权限。
- 1.2,增加代码签名,由类加载器加载到虚拟机中权限不同的运行空间,实现差异化代码执行权限控制
- 1.6,引入域,虚拟机把所有代码加载到不同的系统域和应用域
沙箱基本组件:
- 字节码校验器(bytecode verifier):确保类文件规范。核心类等不需要校验
- 类加载器:防止恶意代码干涉;守护被信任的类库边界;将代码归入保护域,确定其的操作范围。
5 Native
native:带native关键字,说明java的作用范围达不到,需要调用底层C语言的库。带native的方法,会进入本地方法栈,调用本地方法接口(Java Native Interface,JNI),JNI作用:扩展Java,调用不同编程语言为Java用,最初是C和C++(抢地盘背景)。在内存区域中专门开辟了一块标记区域:Native Method Stack,本地方法栈,用来登记 native 方法,在最终执行引擎执行的时候,加载本地方法库中的方法(通过JNI).
程序计数器(Program Counter Register):每个线程都有一个程序计数器,为线程私有,本质为一个指针,指向方法区中的方法字节码(即存储将要执行的指令代码地址).
6 方法区
方法区是JVM中被所有线程共享的运行时内存区域.不同JDK中,方法区中村地数据不一样.所有字段和方法字节码,以及一些特殊方法,如构造函数,接口代码也在此定义,即所有定义的方法信息都保存在该区域.
静态变量(static),常量(final),类信息(Class)(构造方法,接口定义),运行时的常量池存在方法区中,但是实例变量存在堆内存中.
7 栈
栈进出:(FI先进后出,后进先出(桶);队列(FIFO:First Input First Output)
栈:栈内存,主管程序的运行,生命周期和线程同步;线程结束,栈内存释放,栈中不存在垃圾回收
栈存放:8大基本类型+ 对象引用+ 实例的方法
栈运行原理:栈帧,每一个方法从调用开始至执行完成的过程,对应一个栈帧在虚拟机里从入栈到出栈的过程.
对象实例化中:都是先父后子(属性赋值,初始化,构造器等)
具体执行顺序:静态变量,静态代码块 > 变量,代码块 > 构造器
8 三种JVM
- Sun公司 HotSpot(主流)
- BEA JRockit
- IBM J9VM