jvm是什么
虚拟机,一种能够运行java 字节码的虚拟机。
- 类加载子系统
- 加载.class 文件到内存。
- 内存结构
- 运行时的数据区。
- 执行引擎
- 执行内存中的.class,输出执行结果(包含GC:垃圾收集器)。
- 本地方法的接口。
- 本地方法库。
jvm模型
程序计数器
就是一个指针,指向方法区中的方法字节码(用来存储指向下一个指令的地址,也即将要执行的指令代码),由执行引擎读取下一条指令,是一个非常小的内存空间,几乎可以忽略不计。
java虚拟机栈
Java 线程执行方法的内存模型,一个线程对应一个栈,每个方法在执行的同时都会创建一个栈帧(用于存储局部变量表,操作数栈,动态链接,方法出口等信息)不存在垃圾回收问题,只要线程一结束该栈就释放,生命周期和线程一致。
本地方法栈
和栈作用很相似,区别不过是Java 栈为JVM 执行Java 方法服务,而本地方法栈为JVM 执行native 方法服务。登记native 方法,在Execution Engine 执行时加载本地方法库。
堆
Java 虚拟机管理的最大的一块内存区域,Java 堆是线程共享的,用于存放对象实例。也就是说对象的出生和回收都是在这个区域进行的。
方法区
线程共享,用于存储已经被虚拟机加载的类信息、常量、静态变量等数据。
jdk1.8的改变
方法区是由元空间(元数据区)来实现。常量池移到堆中。
类加载的过程
- 加载 将.class 文件从磁盘读到内存。
- 连接
2.1 验证: 验证字节码文件的正确性。
2.2 准备: 给类的静态变量分配内存,并赋予默认值。
2.3 解析: 类装载器装入类所引用的其它所有类。 - 初始化
为类的静态变量赋予正确的初始值,上述的准备阶段为静态变量赋予的是虚拟机默认的初始值,此处赋予的才是程序编写者为变量分配的真正的初始值,执行静态代码块。 - 使用
- 卸载
类加载器的种类
1. 启动类加载器(Bootstrap ClassLoader)
负责加载JRE 的核心类库,如JRE 目标下的rt.jar,charsets.jar 等。
2. 扩展类加载器(Extension ClassLoader)
负责加载JRE 扩展目录ext 中jar 类包。
3. 系统类加载器(Application ClassLoader)
负责加载ClassPath 路径下的类包。
4. 用户自定义加载器(User ClassLoader)
负责加载用户自定义路径下的类包。
类加载机制
- 全盘负责委托机制
当A 类中引用B 类,那么除非特别指定B 类的类加载器,否则就直接使用加载A 类的类加载器加载B 类。 - 双亲委派机制
指先委托父类加载器寻找目标类,在找不到的情况下再在自己的路径中查找并载入目标类。