概述
1.JVM简介
1.1JVM概念
虚拟机简介:JVM(Java Virtual Machine的简称。Java虚拟机。),JVM是一台被定制过的现实中不存在的计算机。
虚拟机:指通过软件模拟的完整的硬件环境功能的、运行在一个完全隔离的环境中的完整计算机系统。
常见虚拟机:JVM、VMwave、Virtual Box
JVM和其他两个虚拟机的区别:
a.VMwave与VirtualBox是通过软件模拟物理CPU的指令集,物理系统中会有很多的寄存器
b.JVM则是通过软件模拟Java字节码指令集,JVM中只是主要保留了PC寄存器,其他寄存器都进行了裁剪
JVM发展史:
最广泛的JVM为HotSpot,在JDK8时整合HotSpot和JRockit VM,优势互补在HotSpot的基础上移植JRockit的优秀特性
2.Java内存区域与内存溢出溢出
2.1运行时数据区域
线程私有区域:程序计数器、Java虚拟机栈、本地方法栈
线程共享区域:Java堆、方法区、运行时常量池
2.1.1程序计数器(线程私有)
记录当前正在执行的虚拟机字节码指令的地址,即线程执行的代码的位置。
在执行一个Native方法时,计数器为空
程序计数器不会出现内存溢出,因为虚拟机中没有规定OOM情况的区域
2.1.2Java虚拟机栈(线程私有)
虚拟机栈描述的是Java方法执行的内存模型:每当方法执行时都会创建一个栈帧用于存储数据,在每个方法从调用直至执行完成的过程,对应一个栈帧在虚拟机栈的出栈与入栈,生命周期与线程相同。
常见异常:
a.StackOverFlowError,栈溢出异常
b.OutOfMemoryError(OOM),动态扩展时无法申请到足够的空间
2.1.3本地方法栈(线程私有)
在HotSpot虚拟机中,本地方法栈与虚拟机栈时同一块区域
2.1.4Java堆(终端java -X 可以设置堆区大小)
Java堆用于存储对象实例
2.1.5方法区
用于存储已被虚拟机加载的类信息,即编译器编译后的代码等数据。
2.1.6运行时常量池(方法区的一部分)
存放字面量与符号引用。
JDK1.7之前在方法区,之后被移到了堆区。
2.2Java堆异常
a.内存泄露
b.内存溢出
2.3虚拟机栈和本地方法栈溢出
a.栈溢出
b.OOM
可以使用递归无出口尝试一下,一般可以递归深度1000-2000.
3.常用JVM性能监控与故障处理工具--了解
3.1JDK命令行工具
3.2jsp--虚拟机进程状态
3.3jstat--虚拟机统计信息监视工具
3.4jinfo--Java配置信息工具
3.5jmap--Java内存映像工具
3.6jhat--虚拟机转存储快照分析工具
3.7jstack--Java堆栈跟踪工具
4.Java内存模型
4.1主内存与工作内存
Java所有的变量都存储于主内存中,每条线程都有自己的工作内存,线程的工作内存中保存了被该线程使用的变量的主内存副本拷贝,线程对变量的所有操作都必须在工作内存中进行,而不能直接读取主内存中的内容,不同的线程之间也无法直接访问对方的工作区,线程间变量值传递需要通过主内存来完成。
线程、主内存、工作内存关系:
4.2内存间交互操作
lock(锁定):作用于主内存的变量,它把一个变量标识为一条线程独占的状态
unlock(解锁):作用于主内存的变量,它把一个处于锁定状态的变量释放出来,释放后的变量才可以被其他线程锁定
read(读取):作用于主内存的变量,它把一个变量的值从主内存传输到线程的工作内存中,以便以后的load动作使用
load(载入):作用于工作内存的变量,它把read操作从主内存中得到的变量值放入工作内存的变量副本中
use(使用):作用于工作内存的变量,它把工作内存的一个变量的值传送给执行引擎
assign(赋值):作用于工作内存的变量,它把一个从执行引擎收到的值赋给工作内存中的变量
store(存储):作用于工作内存的变量,它把工作内存的一个变量的值传送到主内存中,以便后续的write操作使用
write(写入):作用于主内存的变量,它把store操作从工作内存中得到的变量的值放入主内存的变量中
Java内存模型的三大特性
原子性:由Java内存模型直接保证原子性变量操作包括read、load、assign、use、store、write,大致可以认为,基本数据类型的访问读写是具备原子性的,如需大范围的原子性,则需要synchronized关键字
可见性:可见性指当一个线程修改了共享变量的值,其他线程能够立即得知修改,volatile、final、synchronized关键字可以保证可见性
有序性:如果在本线程内观察,所有的操作都是有序的,如果在线程中观察另外一个线程都是无序的。
Java内存模型具备一些先天有序性,这个称为happens-before原则。如果俩个操作无法从happens-before原则推导出来,那么久不能保证有序性,虚拟机可以随意进行重排序
happen-before原则:
程序次序规则:一个线程内,按照代码顺序,书写在前面的操作先行发生于书写在后面的操作
锁定规则:一个unlock操作先行发于后面对同一个锁的lock操作
volatile变量规则:对一个变量的写操作先行发于后面对这个变量的读操作
传递规则:如果操作A先行发生于操作B,而操作B又先行于操作C,则可以得出操作A先行发生于操作C
线程启动规则:Thread对象的start()方法先行发生于此线程的每一个动作
线程中断规则:对线程interrupt()方法的调用先行发于被中断线程的代码检测到中断事件的发生
线程终结规则:线程中所有的操作都先行发生于线程的终止检测,我们可以通过Thread.join()方法结束、Thread.isAlive()的返回值手段检测到线程已经终止执行
对象终结规则:一个对象的初始化完成先行发生于它的finalize()方法的开始
4.3volatile型变量的特殊规则
volatile是JVM提供的最轻量级的同步机制,JVM内存模型对volatile专门定义了一些特殊访问规则。
两种特性:
保存此变量对所有线程的可见性
使用volatile变量的语义是禁止指令重排序
禁止指令重排的俩层意思:
a.当程序执行到volatile变量的读操作或者写操作时,在其前面的操作的更改肯定全部已经进行,且结果已经对后面的操作可见,在其后的操作肯定没有进行
b.在进行指令优化时,不能将在对volatile变量访问的语句放在其后面执行,也不能把volatile变量后面的语句放在其前面执行
注意:volatile修饰的变量是多线程可见,但是volatile修饰的变量进行运算,不保证原子性
最后
以上就是微笑大神为你收集整理的走进JVM1.JVM简介2.Java内存区域与内存溢出溢出3.常用JVM性能监控与故障处理工具--了解4.Java内存模型的全部内容,希望文章能够帮你解决走进JVM1.JVM简介2.Java内存区域与内存溢出溢出3.常用JVM性能监控与故障处理工具--了解4.Java内存模型所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复