JVM内存模型分析&&简单的常量赋值过程分析JVM内存模型&&新生代、老年代的Gc过程
2020-12-08 10:03:31 0 举报
JVM内存模型分析&&简单的常量赋值过程分析JVM内存模型&&新生代、老年代的Gc过程
作者其他创作
大纲/内容
动态链接
Old Generation
Thread
Native MethodStacks(本地方法栈)
Survivor Space
main
a=3
程序计算器
from
1、局部变量表(Local Variable Table):是一组变量值内存存储空间,最小单位是Slot(变量槽),用于存放方法参数和方法内部定义的局部变量。在java编译Class文件是,就已确定了该方法所需要分配的局部变量表的最大容量。2、局部变量表存放了编译期可知的各种基本数据类型、对象引用(reference类型)和returnAddress类型(指向了一条字节码指令的地址)注意:局部变量存储在局部变量表中,随着线程生和灭,并且线程间的数据不共享。但如果是成员变量,或定义在方法外的对象的引用,都是存储在堆中。
方法的返回地址
简单的常量赋值过程
java内存中最大的一块,所有的对象实例、数组都放在java堆中,GC回收的地方,存放的对象都是线程共享的。JAVA堆=老年代+新生代
本地方法栈:与虚拟机栈发挥作用相似,区别是虚拟机栈执行的是Java方法(也就是字节码)服务,而本地方法栈则为了虚拟机使用到的native方法服务的,来完成对操作系统乃至是硬盘的操作。
MetaData Space
方法区同堆一样,是所有线程共享的内存区域,为了区分堆,又叫非堆。用来存储已被虚拟机加载过的类信息、常量池(常量)、静态变量,比如static修饰的变量,在加载类的时候就会被加载到方法区。元数据区就是方法区概念的新体现,元数据区放在本地内存中,就是为了避免之前的永久区的内存溢出。
局部变量区
操作数栈
将int常量 1 存入到局部变量中
局部变量表
1、java的虚拟机栈都是线程私有的,生命周期与线程同步。(随线程生和灭);2、如果线程请求的栈深度大于虚拟机所允许的最大深度,就会抛出StackOverflowError异常;3、如果虚拟机栈进行动态扩展,在扩展时无法申请到足够的内存,就会抛出OutOfMemoryError异常(当前大部分jvm虚拟机都可以动态扩展,只不过巨幕规范也允许固定长度的虚拟机栈)4、每个方法执行的提示都会创建一个栈帧。
(方法区)
Java栈
MetaDate
运行时数据区Runtime Data Areas
操作数栈:存储的数据与局部变量表一致,含各种基本数据类型、对象引用(reference类型)和returnAddress类型(指向了一条字节码指令的地址),操作数栈中的byte、short、char压栈前(bipush)会被转成int。但数据是后进先出,通过标准的入栈和出栈操作来完成一次数据访问。可理解为Java虚拟机栈中的一个用于计算的临时数据存储区。作用:1.栈帧刚创建时,里面的操作数栈是空的。2、Java虚拟机提供指令来让操作数栈对一些数据进行入栈操作,比如可以把局部变量表的数据、实例的字段等数据入栈。同时也有对应的指令来支持出栈操作。3、向其他方法传的参数和返回的结果,也会存储在操作数栈中。
To
本地方法栈
Young Generation
Heap
栈帧
将int常量 1 压入栈
线程执行mathTest方法
JVM Stacks(虚拟机栈)
栈的先进后出:main方法先进栈,调用的方法位于栈顶。每调用一个方法就对应一个站址
无论方法是否正常完成,都需要返回到方法被调用的位置,程序才能继续进行。比如:一个简单的测试类,main方法启动,后面调用的每个方法执行后,都要返回到main方法上,接着执行后面的逻辑,那么就需要通过返回地址回到被调用的位置。
Tenured Space
Eden
Program Counter Register(程序计数器)
Heap(堆)
活动线程:当前CPU调用的线程里面包含了一个虚拟机栈、一个本地方法栈和一个程序计数器
int a=3;
3
1、栈帧:用来存储数据和部分过程结果的数据结构,是虚拟机栈的栈元素。每个方法的调用和结束代表着栈帧的入栈和出栈,2、结构(存储的数据):局部变量表。操作数栈。动态链接。方法返回地址。3、活动线程:一个虚拟机栈对应一个线程,当前CPU调度的那个线程叫做:活动线程。4、当前栈帧:一个栈帧对应一个方法,活动线程的虚拟机栈里最顶层的栈帧代表了当前正在执行的方法,而这个栈帧也被叫做当前栈帧。
mathTest
为何jdk1.8要把方法区从JVM里移到直接内存中?①、因为直接内存,JVM将会在IO操作上具有更高的性能,因为它是直接作用于本地系统的IO操作,而非直接内存,也就是堆内存中的数据,如果需要做IO操作,需要先复制到直接内存,再利用本地IO处理。从数据流的角度,非直接内存的作用链:本地IO-->直接内存--->非直接内存--->直接内存---->本地IO而直接内存的作用链:本地IO--->直接内存---->本地IO②、整个永久代有一个JVM本身设置的固定大小上限,无法进行调整,而元空间使用的是直接内存,永远不会得到OutOfMemoryError,而且可用 -XX:MaxMetaspaceSize 标志设置最大元空间大小,默认值为 unlimited。这意味着它只受本机可用内存的限制。 -XX:MaxMetaspaceSize 调整标志定义元空间的初始化大小,如果未指定此标志,则Metaspace将根据运行时的应用程序需求动态的重新调整大小。
1、Java虚拟机栈中,每个栈帧都包含一个 指向运行是常量池中 该栈所属方法的 符号引用。持有这个引用的目的就是为了支持方法调用过程中的动态链接(Dynamic Linking)。2、动态链接就是多态的应用,比如定义一个集合 Map<> map = new HashMap<>();这个Map是一个接口,我们用map.put()的时候,实际调用了Map的实现类HashMap,这里就是通过动态链接动态的调用了HashMap。
当多个线程执行时,也就是线程间进行轮转,当线程需要切换时,记录当前线程执行到哪里了,当线程切换回来的时候,需要程序计数器来为该线程指明接着从哪里执行。程序计数器是私有的,每个线程一个
RuntimeConstant pool运行时常量池
0 条评论
回复 删除
下一页