微信网站设计分析,linux系统做网站,集团有限公司,手机wap网站源码文章目录 一、前言二、JVM内存模型1、Java堆2、方法区3、Java栈3.1、局部变量表3.2、操作数栈3.3、动态链接3.4、返回地址 4、本地方法栈5、程序计数器 一、前言
本文将详细介绍JVM内存模型#xff0c;JVM定义了若干个程序执行期间使用的数据区域。这个区域里的一些数据在JVM… 文章目录 一、前言二、JVM内存模型1、Java堆2、方法区3、Java栈3.1、局部变量表3.2、操作数栈3.3、动态链接3.4、返回地址 4、本地方法栈5、程序计数器 一、前言
本文将详细介绍JVM内存模型JVM定义了若干个程序执行期间使用的数据区域。这个区域里的一些数据在JVM启动的时候创建在JVM退出的时候销毁。而其他的数据依赖于每一个线程在线程创建时创建在线程退出时销毁。
二、JVM内存模型 在谈 JVM 内存区域划分之前我们先来看一下 Java 程序的具体执行过程 Java 源代码文件经过编译器编译后生成字节码文件然后交给 JVM 的类加载器加载完毕后交给执行引擎执行。在整个执行的过程中JVM 会用一块空间来存储程序执行期间需要用到的数据这块空间一般被称为运行时数据区也就是常说的 JVM 内存。
所以当我们在谈 JVM 内存区域划分的时候其实谈的就是这块空间——运行时数据区。
JVM内存模型主要分为五块Java 堆内存(Heap)、方法区(Method Area)、JVM栈(JVM Stack)、本地方法栈Native Method Stacks、程序计数器Program Counter Register。 1、Java堆
对于大多数应用来说Java堆Java Heap是Java虚拟机所管理的内存中最大的一块。Java堆是被所有线程共享的一块内存区域在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例几乎所有的对象实例都在这里分配内存。
堆是垃圾收集器管理的主要区域因此很多时候也被称做“GC堆”。 堆由老年代和新生代组成新建的对象一般都是在存放在Eden区当Eden区不够用时就会就行Minior GC回收垃圾对象释放内存空间当垃圾回收后仍然存活的对象就会放到S0和S1其中一块区域当再次发生Minior GC时会把Eden区和有对象的S区中的存活对象移动到另外一块空的S区这时先前有对象的S区又变成空的S区所以S0和S1是相互转化的当S区对象达到一定的阈值时新生代的对象就会向老年代转移当老年代的对象达到一定阈值时就会触发Full GC
新生代 Eden伊甸园区 2个survior区(幸存者区)
YGC回收之后大多数的对象会被回收(90%)活着的进入s0再次YGC活着的对象eden s0 - s1再次YGCeden s1 - s0年龄足够 - 老年代 15 CMS 6s区装不下 - 老年代 老年代顽固分子老年代满了FGC Full GC
2、方法区
方法区Method Area与Java堆一样是各个线程共享的内存区域它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
1.7之前 方法区的实现是永久代
1.8之后 方法区的实现是元空间
这里有个注意点必须给大家提醒一下那就是该区域并不会存放Class对象Class对象是存放在堆中的方法区存放的类信息是一些代码片段类似于C语言中的结构体供我们程序调用时字节码执行引擎解释执行的。
3、Java栈
线程私有它的生命周期与线程相同。一个线程一个栈一个方法一个栈帧。虚拟机栈描述的是Java 方法执行的内存模型每个方法被执行的时候都会同时创建一个栈帧Stack Frame用于存储局部变量表、操作栈、动态链接、方法出口等信息。每一个方法被调用直至执行完成的过程就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。
对于执行引擎来说活动线程中只有栈顶的栈帧是有效的称为当前栈帧这个栈帧所关联的方法称为当前方法。执行引擎所运行的所有字节码指令都只针对当前栈帧进行操作。
3.1、局部变量表
局部变量表存放了编译期可知的各基本数据类型byte、short、int、long、float、double、boolean、char、对象引用、retrunAddress类型指向了一条字节码指令的地址。概况来说局部变量表用于存放方法参数和方法内部定义的局部变量。
3.2、操作数栈
在方法执行过程中根据字节码指令往栈里写入数据或提取数据即入栈/出栈。
数据运算的地方大多数指令都在操作数栈弹栈运算然后结果压栈。
操作数栈主要用于保存计算过程的中间结果同时作为计算过程中临时的存储空间。
3.3、动态链接
每一个栈帧内部都包含一个指向运行时常量池中该栈帧所属方法的引用包含这个引用的目的就是为了支持当前方法的代码能够实现动态链接(Dynamic Linking)
jvm虚拟机栈中的动态链接是将符号引用转换成直接引用因为java具有多态特性父类引用调用方法时如果子类重写了该方法那么实际父类引用是会调用子类方法的因此是需要在运行时期进行动态调用的而不是在类加载的解析阶段能够确定的。
3.4、返回地址
方法的返回分为两种情况一种是正常退出退出后会根据方法的定义来决定是否要传返回值给上层的调用者一种是异常导致的方法结束这种情况是不会传返回值给上层的调用方法。
方法的的一次调用就对应着栈帧在虚拟机栈中的一次入栈出栈操作因此方法退出时可能做的事情包括恢复上层方法的局部变量表以及操作数栈如果有返回值的话就把返回值压入到调用者栈帧的操作数栈中还会把PC计数器的值调整为方法调用入口的下一条指令。
4、本地方法栈
本地方法栈Native Method Stacks与虚拟机栈所发挥的作用是非常相似的其区别不过是虚拟机栈为虚拟机执行Java 方法也就是字节码服务而本地方法栈则是为虚拟机使用到的Native 方法服务。
5、程序计数器
程序计数器是一块较小的内存空间可以看作是当前线程所执行的字节码的行号指示器。用于记录线程执行到哪一行代码。分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。