jvm执行过程
Jvm
Class文件通过类加载器加载到jvm运行时数据区(类加载器:双亲委派)
运行时数据区包括 线程共享区 和线程私有区,
线程共享区里面包括java堆和方法区
java堆存的是解释class文件创建的对象,是gc的工作区
方法区存放的是class的结构信息,例如常量池,字段方法,构造函数
线程私有区存放的是线程栈 ,程序计数器 ,本地方法栈
Java栈:用来存放栈帧,栈帧主要包含:局部变量表,操作数栈
程序计数器:纪录当前cpu执行到了哪一行
本地方法栈:支持native方法的执行,一般native方法由c或c++实现
执行引擎:负责解释执行加载到 方法区的数据,
总体流程:
- 类加载器加载class文件到方法区
- 执行引擎读取数据方法区内容并执行
- 创建线程栈
- 运行中产生复杂类型数据存入堆中
Gc:垃圾回收
- class文件在硬盘里
- 通过类加载器加载到jvm里面,jvm里面有三个区,方法区,堆和栈
栈分为很多栈 ,有一个线程栈
类加载器:双亲委派加载机制
加载过程中,会委托相关联的双亲加载器加载,之后再自己加载,这确保了jvm自带的库都能够被正确加载
核心库 扩展库 用户类
启动类加载器 ---》扩展类加载器---》应用程序类加载器 ---》自定义类加载器,
核心库的作用:这个是java的创世纪加载器,把内存中java世界开创出来,让计算机识别java代码
运行时的数据区
程序计数器的作用;保存当前线程执行的哪个进度点了
执行引擎 三个部分
解释器:读取字节码指令,并串行执行
Jit:编译器,这里的编译是将字节码编译成系统特定的指令,
Gc:垃圾回收器
是jvm自动内存管理的机制
引用计数法:计算引用次数,不太合理
标记清理法:gc-root 主方法
没有被引用的对象被称为垃圾,将会被清理
Gc算法通用步骤
- 标记 2)清理
标记阶段:
从gc-root对象开始遍历整个jvm内存,标记处出哪些是存活的对象,遍历结束后,没有被标记的对象就是垃圾对象
这种标记需要stw 就是全世界停止运行,只执行gc标记算法
停止的时间长度是源于内存中有多少对象,增加内存并不能改变 stw的长度
清理阶段:三种方式 1)清理 2)压缩 3)拷贝
清理是单纯的删除 ,但是会空出一片一片的地方
清理-压缩 是删除完之后,再次把内存压缩在一起,这样后面再次添加就会方便很多
拷贝是将内存分为两片区域:1 源内存区 2新内存区 ,stw的时候存活对象,同步放入2内存区,这样源内存区都是垃圾,都可以进行覆盖
分代管理:大部分的对象很快就变成垃圾,一般不会存活太久
内存分为年轻代和年老代
年轻代里面用的是标记-拷贝算法
年老代里面用的是内存占用较少的方式 标记-清理-压缩
年轻代管理
首先划分三块区域
初始区域--内存1--内存2
首先初始区域将存活数据拷贝到内存1---> 下一次就把初始区域和内存1扫描,存活数据放入内存2,这样反复交替。当15次都没有被清除的就进入年老代
标记就是标记,清理压缩实现了,这样stw的时间就