JVM
2020-09-07 15:57:11 150 举报
AI智能生成
JVM是Java虚拟机的缩写,它是Java程序运行的基础。JVM是一种抽象的计算机,它有自己的指令集和执行引擎,可以将Java字节码翻译成机器语言并执行。JVM的主要作用是提供一种平台无关性,使得Java程序可以在任何支持Java的平台上运行,而不需要重新编译。JVM还负责管理内存、垃圾回收和异常处理等任务,确保Java程序的稳定性和高效性。JVM有多种实现,如HotSpot、JRockit和OpenJDK等,它们在性能和功能上有所不同。总之,JVM是Java技术的核心组件,为Java程序提供了强大的运行环境和灵活性。
作者其他创作
大纲/内容
内存结构
方法区
方法区是各个线程共享的运行时内存区,用来存储类的元数据信息——类的版本,字段,方法,接口和常量池
方法区存着类的信息,常量和静态变量,即类被编译后的数据,可以理解为class文件进入内存后的位置
方法区存着类的信息,常量和静态变量,即类被编译后的数据,可以理解为class文件进入内存后的位置
JDK1.6及以前
运行时常量池是方法区的一个部分
JDK1.7及以后
将运行时常量池与方法区分开,在JVM堆内存中开辟了一块空间作为常量池
在JDK1.8,取消了方法区(永久代),取而代之的是元数据区,用于存放类的元数据信息,
该区存在于自己电脑的物理内存中,而非jvm内存
该区存在于自己电脑的物理内存中,而非jvm内存
堆内存
是被所有线程共享的一块区域,是jvm管理的内存中最大的区域,在虚拟机启动的时候创建
几乎所有的对象的实例和数组都在堆中分配内存。是垃圾回收器主要管理的区域
几乎所有的对象的实例和数组都在堆中分配内存。是垃圾回收器主要管理的区域
分区
新生代
Eden(伊甸区)
新建对象存在于这个区
From Survivor空间
To Survivor空间
老年代
堆内内存
堆内内存是指JVM虚拟机堆的堆内存
堆外内存
产生
为了防止堆内内存过大,导致在触发FullGC时程序卡顿以及
操作系统对堆内内存的不可知性出现了堆外内存
操作系统对堆内内存的不可知性出现了堆外内存
堆外内存意味着把一些对象的实例分配在Java虚拟机堆内内存以外的电脑的直接物理内存区域
特点
对于大内存有良好的伸缩性
对垃圾回收停顿的改善可以明显感觉到
在进程间可以共享,减少虚拟机间的复制
程序计数器
用来记录程序运行到哪行代码,字节码解释器工作时,通过改变这个计数器的值来选取下一条需要执行的字节码指令
循环、分支、跳转、异常处理、线程恢复等基础功能都需要依赖这个程序计数器来完成
循环、分支、跳转、异常处理、线程恢复等基础功能都需要依赖这个程序计数器来完成
与线程同生共死,不必考虑它的回收
特点
如果线程正在执行的是Java 方法,则这个计数器记录的是正在执行的虚拟机字节码指令地址
如果执行的是native方法,则程序计数器为undefined
虚拟机栈
生命周期与线程生命周期相同
平时所说的栈就是虚拟机栈,代表方法执行的内存模型
每个方法在执行的同时都会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、返回值、
返回地址等信息,每一个方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。
返回地址等信息,每一个方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。
内部结构
局部变量表用于存储方法使用的局部变量
动态链接是将符号引用转换为直接引用
操作数栈:实际上程序的运行都是以通过操作数栈来跑的,操作数栈会将局部变量一一推向局部变量表并复制
回来,需要进行计算的就会抛出推给cpu的寄存器,让寄存器进行运行,最后再推向局部变量表,让程序向下执行
回来,需要进行计算的就会抛出推给cpu的寄存器,让寄存器进行运行,最后再推向局部变量表,让程序向下执行
返回地址:实际上就是方法的出口,本质上就是指向一个地址,该地址就是调用该方法的对象,在程序执行完方法后,需要知道
接下来该继续执行哪里,在执行过程中,程序计数器也一直在记录着指令运行到哪里
接下来该继续执行哪里,在执行过程中,程序计数器也一直在记录着指令运行到哪里
本地方法栈
与虚拟机栈类似
为本地native方法服务
HotSpot将本地方法栈与虚拟机栈合二为一
内存模型JMM
内存模型与内存结构不是一个概念层次,内存结构讲述的是虚拟机管理的内存的区域划分,而内存模型可以理解为是一种规范
或者说是一种规则,描述了在虚拟机管理的内存中,线程在共享数据区和线程私有数据区之间对各个变量的访问方式
或者说是一种规则,描述了在虚拟机管理的内存中,线程在共享数据区和线程私有数据区之间对各个变量的访问方式
主内存
主内存是线程共享区域,可以将主内存理解为内存结构中的共享数据区,即堆和方法区
主要存储的是类的实例,所有线程创建的类的实例都会存放在主内存
由于主内存是线程共享的,所以在多线程环境下可能出现线程安全问题
工作内存
工作内存是线程私有的数据区,主要存储当前方法的所有本地变量信息(存储从工作区拷贝的变量副本)
每个线程的工作内存只能自己访问,其中的本地变量对其他线程是不可见的,就算是两个线程执行同一段方法体,它们也会
在各自的工作内存中创建属于当前线程的主内存共享变量的副本
在各自的工作内存中创建属于当前线程的主内存共享变量的副本
虚拟内存分为两块区域,一块称为主内存,一块称为工作内存,线程在访问各个变量时需要从主内存中复制到
自己的私有空间即自己的工作内存,用完再将变量放回主内存
自己的私有空间即自己的工作内存,用完再将变量放回主内存
常量池
常量池里存储着字面量和符号引用。
字面量
符号引用
class文件常量池
运行时常量池
字符串常量池
内存配置参数
-Xms
JVM启动时申请的初始堆内存,也为最小内存
-Xmx
JVM可申请的最大堆内存
-Xmn
Java堆内存的年轻代区
Eden区
From Survivor
To Survivor
-XXSurvivorRatio
年轻代中Eden区与Survivor区的大小比值
若-XXSurvivorRatio=3,意思就是Eden区和一个Survivor的比为3:1
GC机制
要回收的内存
方法区
堆内存
不考虑的内存
程序计数器
虚拟机栈
本地方法栈
判断一块内存是否符合回收标准的标准
对象被赋为null并且以后再也没调用过
对象被赋为null并重新分配内存
内存泄漏是指程序中一个不再被引用的对象或者不再被使用的变量一直占据着内存不释放
判断对象存活
引用计数法
可达性分析算法
二次标记
垃圾回收算法
标记-清除算法
在二次标记完成后统一回收
产生问题
标记-整理算法
复制算法
分代收集算法
内存分配策略
新生代
又分为Eden区
新建对象存在于这个区
两个Survivor
这两个区域是为了复制算法
在新生代执行GC回收被称为Minor GC
老年代
大对象直接在老年代中分配,大对象指需要大量连续内存空间的Java对象。
老年代满了则触发Full GC
在老生代执行GC回收被称为Full GC
如何判定对象的年龄
图解
垃圾回收器
CMS
标记-清除算法
缺点
无法处理浮动垃圾导致内存零散,当需要较大内存时会触发GC回收
G1
整体上使用标记-整理算法
占cpu
新生代串行/并行收集器
复制算法
老年代串行收集器
标记-清除算法
老年代并行收集器
标记-整理算法
0 条评论
下一页