(一) 概述:
全称:java virtual machine(java 虚拟机) 是一个进程 用来模拟计算单元 将.class文件转成计算机能够识别的指令
注:jvm是 java 语言跨平台性(一次编译到处运行)的基础
(二) JVM虚拟机运行的流程:
1.读取字节码文件所在的路径
//类加载机制
- 获取字节码文件中的内容
//方法区(元数据区)用来存放类的描述信息
3.获取该类的实例(对象)
//堆 用来存储对象
4.通过对象名.的方式调用方法
//栈 用来存放局部变量及所有代码执行的
(三) JVM虚拟机的类加载机制
JVM 底层加载类依靠三大组件:
BootStrapClassLoader 启动类加载器
负责加载 : jre /lib/ rt.jar
ExtClassLoader 扩展类加载器
负责加载: jre/lib/ext/* 文件夹下所有的jar 包
注:这俩个加载器执行完毕后,JVM虚拟机基本上就初始化完毕了
APPClassLoader 应用程序加载器
负责加载用户自定义的类的
// UserClassLoader //自定义加载器
//自定义加载器就是自定义一个类继承classloader 然后重写 findclass(),loadclass()俩个方法即可
加载顺序: BootStrap --> ExtClassLoader --> AppClassLoader --> UserClassLoader
(四) JVM虚拟机加载机制(二):检查顺序
加载顺序:
BootStrap-->ext-->app
检查顺序:
app-->ext-->BootStrap
app检查A.class是否加载: 是: 不加载A.class 否: 加载A.class
ext检查A.class是否加载: 是: 不加载A.class 否: 加载A.class
bootstrap先加载 A.class
对如: UserClassLoader APPClassLoader ExtClassLoader BootStrapClassLoader 总结: 自上而下检查, 自下而上运行.
(五) JVM的内存模型
1 ) A.class字节码文件被加载到内存
//存储在方法区中,并且方法区中包含常量池
2)创建本类的实例对象,存储在堆中(heap)
3)通过对象名.的形式调用方法,方法的执行过程是在:虚拟机栈中完成的
//一个线程对应一个虚拟机栈,每一个方法对应一个:虚拟机栈中的栈帧
4)程序计数器区域记录的是当前程序的执行位置 ,例如
线程1:print(),第三行
5)将具体要执行的代码交给:执行引擎来执行
6)执行引擎调用:本地库接口 本地方法库来执行具体的内容
本地方法栈:就是本地方法的执行的区域(底层C语言,外部库运行的空间)</p> </li> <li> <p>直接内存 :当JVM内存不够用的时候,会找操作系统借点内存
(六) 线程安全和内存溢出的问题
存在线程安全问题的模块
堆:会 // 多线程 ,并发 .操作同一数据 栈 :不会 //线程栈之间是相互独立的
方法区:不会 //存储常量,类的描述信息
程序计数器 :不会 //记录程序的执行流程
存在内存溢出问题的模块
堆:会 //不断创建对象,内存被撑爆
栈:会 //不断调用方法 内存被撑爆
方法区 :会 常量过多 .class文件过大
程序计数器 :会//理论上讲会 因为线程过多,导致计数器过多
(七) JDK1.7的堆内存的垃圾回收算法
jdk 1.7将堆内存划分为三部分 年轻代 ,年老代,持久代 (就是方法区)
年轻代又分为三个区域:使用的是复制算法
Eden:伊甸园
//存储的新生对象,当伊甸园满的时候,会将存活对象复制到S1区,并将移除那些垃圾对象
survivor: 幸存者区1
//当该区域满的时候,会将存活的对象复制到S2区 并将移除那些垃圾对象
survivor:幸存者区2
//当该区域满的时候 会将存活对象复制到S1区 并移除到那些垃圾对象
注:S1区和S2区是来回互相赋值的
年老代: 使用的是标记清除算法,标记整理算法
当对象在S1区和S2区之间来回复制15次 才会加载到 年老代
当年轻代和年老代都全部装满的时候就会报堆内存溢出
持久代 :就是方法区 存储常量,类的描述信息
JDK 1.7 默认垃圾回收器
serial 收集器 :单线程收集器,它使用一个cpu或者一个线程来回收对象 它在垃圾收集的时候必须暂停其它工作线程,直到垃圾回收完毕
Parnew 收集器 :多线程收集器
Paraller scavenge 收集器 是一个新生代的收集器 并且使用复制算法 而且是一个并行的多线程收集器 其它收集器是尽量缩短垃圾收集时用户线程的停顿时间 而parallel scavenge收集器的目标是达到一个可控制的吞吐量
CMS收集器 :主要针对于年老代 精细化运营 前边的垃圾收集器都是一刀切(在回收垃圾的时候其它线程都是等待) 而cms是尽可能降低等待时间 并行执行程序,提高运行效率
(八) jdk 1.8 以后的垃圾回收器 G1垃圾回收器 在jdk 1.9的时候成了默认的垃圾回收器
G1垃圾回收器
1)将内存划分为同样大小的region区域
2)每个region既可以是年轻代也可以是年老代,还可以是幸存者区
3)程序运行前期,创建大量对象的时候可以将每个region看做是Eden (伊甸园)
4)程序运行中期 可以将Eden的region变成survivor
5)程序运行后期 可以缩短Eden Survivor 的区域变成old区域
6)H:存储大对象
注:方法区从JVM模型中迁移出去了完全使用系统的内存 方法区也改名叫元数据区
来源:oschina
链接:https://my.oschina.net/u/4140673/blog/3056230