JVM运行时的内存结构

我们都知道,JVM的垃圾收集机制能够帮开发者自动管理内存,了解JVM运行时的内存结构是理解垃圾收集机制的前提。本文主要简单介绍JVM运行时的内存结构。

【JVM运行时内存中不同的数据区域】

一、PC寄存器

做过嵌入式开发或者底层编程的朋友应该都知道PC寄存器的作用,它就相当于在程序流中的游标,指示线程当前的运行位置。但是要注意,如果虚拟机执行的是本地native方法,则PC寄存器为undefined状态。

一个线程持有一个独立的PC寄存器。

二、java栈

每一个JVM线程都会拥有一个java栈,java栈伴随着线程的创建而创建。java栈中存放着多个java帧,至于什么是java帧会在文章后面介绍。

三、java堆

JVM所有线程之间共享,存放类实例和数组对象。

四、方法区

JVM所有线程之间共享,存放编译代码。

五、运行时常量池

JVM所有线程之间共享,存放在方法区中,对应于class文件中每一个类或者接口的常量池表。

六、本地方方法栈

一个线程拥有一个,在native方法执行时使用。

【栈帧介绍】

线程中的每个方法被调用的时候JVM都会生成一个栈帧,栈帧存放在线程的java栈中。栈帧主要保存一下几种内存类型。

一、局部变量表

一个变量列表。变量的类型是原生类型或者引用类型。这里面存放都是局部变量,比如说方法的参数和方法内部定义的变量。一个java程序在编译成class文件的时候局部变量表的最大容量就已经被确定了。

二、操作数栈

存放操作数,如相加指令中的两个加数和结果。

三、动态链接

要理解动态了解首先要了解JVM对方法的调用过程。JVM的运行时常量池保存了大量的符号引用,有些符号引用可以看成是方法的间接引用。JVM在需要调用某个方法时需要将符号引用(也就是方法的间接引用)转变成方法在内存中的直接引用。如果JVM是在类加载或者引用符号第一次使用的时候将引用符号转变成方法的直接引用,这种转换叫静态链接;如果JVM是在运行期间将引用符转变成方法的直接引用,则这种转变叫做动态链接。

简单来说,栈帧中的动态链接就是帮助JVM在执行某个方法是调用其他方法。

四、方法的返回

JVM的方法返回分为两种情况,一种是正常结束返回,另外一种是异常结束返回。正常结束返回时,方法会把返回值交给方法的调用者;异常结束时,方法不会有返回值,而是让调用者处理异常。

时间: 2024-10-11 19:01:02

JVM运行时的内存结构的相关文章

利用jmap和MAT等工具查看JVM运行时堆内存

jmap JDK自带了一些工具可以帮助我们查看JVM运行的堆内存情况,常用的是jmap命令 jmap -heap <pid> 打印堆的使用情况 那么,从这个输出中我们也可以大致看出堆的结构,分为Young Generation (年轻代) 和 Old Generation (老年代) Young Generation又被划分为:Eden Space , From Space 和 To Space 可以看到这里To区是干净的,还未被使用,From区已经使用了95%了 jmap -histo[:l

JVM运行时的内存划分--JDK1.8

对比JDK1.7,JDK1.8在运行时的内存分配上进行了调整.本篇对JDK1.8版本进行简要介绍. 先以一张图片描述运行时内存: 程序计数器 记录当前线程执行的字节码行号.如果执行的是native方法,值为null. 虚拟机栈 每一个线程执行时,都对应有一个虚拟机栈,生命周期与线程相同.一个虚拟机栈有一个一个的栈帧组成,每个java方法被调用时都会创建一个栈帧,然后入栈,方法结束后出栈.一个栈帧由局部变量表,操作数栈,动态链接和方法出口信息组成. 如果方法中出现递归调用死循环,或者栈帧大小超过虚

JVM 运行时的内存分配

首先我们必须要知道的是 Java 是跨平台的.而它之所以跨平台就是因为 JVM 不是跨平台的.JVM 建立了 Java 程序和操作系统之间的桥梁,JVM 是用 C 语言编写,而 C 语言不具备跨平台的特性.所以对于 Windows 平台,Java 有基于 Windows 平台的 JVM:对于 Linux 平台,Java 也有基于 Linux 平台的 JVM等等.不同的操作系统有不同的 JVM,所以我们编写的 Java 代码能在各个平台上运行,是因为有各个平台的 JVM. 而 Java 的内存分配

实例分析C程序运行时的内存结构

先验知识 静态变量存储在静态存储区,局部变量存储在动态存储区(栈),代码存放在代码区 寄存器,EBP指向栈底,ESP指向栈顶,EIP指向正在执行指令的下一条指令,三个寄存器中保存的都是地址,32位系统,地址为4个字节即dword 所有写在函数定义里面的语句都编译成指令(驱动CPU) 实验代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #include <stdio.h> int fun(int a, int b); int m = 10; int main() {

程序编译后运行时的内存分配

原文地址不详,我的转载的来源:http://blog.sina.com.cn/s/blog_5420e0000101a0w1.html 一.编译时与运行时的内存情况 1.编译时不分配内存 编译时是不分配内存的.此时只是根据声明时的类型进行占位,到以后程序执行时分配内存才会正确.所以声明是给编译器看的,聪明的编译器能根据声明帮你识别错误. 2.运行时必分配内存 运行时程序是必须调到"内存"的.因为CPU(其中有多个寄存器)只与内存打交道的.程序在进入实际内存之前要首先分配物理内存. 3.

[转]JVM运行时内存结构

目录[-] 1.为什么会有年轻代 2.年轻代中的GC 3.一个对象的这一辈子 4.有关年轻代的JVM参数 1.为什么会有年轻代 我们先来屡屡,为什么需要把堆分代?不分代不能完成他所做的事情么?其实不分代完全可以,分代的唯一理由就是优化GC性能.你先想想,如果没有分代,那我们所有的对象都在一块,GC的时候我们要找到哪些对象没用,这样就会对堆的所有区域进行扫描.而我们的很多对象都是朝生夕死的,如果分代的话,我们把新创建的对象放到某一地方,当GC的时候先把这块存“朝生夕死”对象的区域进行回收,这样就会

JVM 运行时内存结构

  1.JVM内存模型       JVM运行时内存=共享内存区+线程内存区 1).共享内存区       共享内存区=持久带+堆       持久带=方法区+其他       堆=Old Space+Young Space       Young Space=Eden+S0+S1 (1)持久带       JVM用持久带(Permanent Space)实现方法区,主要存放所有已加载的类信息,方法信息,常量池等等.可通过-XX:PermSize和-XX:MaxPermSize来指定持久带初始化

JVM运行时内存结构

连接:http://my.oschina.net/sunchp/blog/369707 1.JVM内存模型 JVM运行时内存=共享内存区+线程内存区 1).共享内存区 共享内存区=持久带+堆 持久带=方法区+其他 堆=Old Space+Young Space Young Space=Eden+S0+S1 (1)持久带 JVM用持久带(Permanent Space)实现方法区,主要存放所有已加载的类信息,方法信息,常量池等等. 可通过-XX:PermSize和-XX:MaxPermSize来指

Java 进阶(一) JVM运行时内存模型

1.JVM运行时数据区域的划分 a.程序计数器(Program Counter Register) 一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器.每个线程拥有独立的一个计数器,如果当前执行的是Native方法,则计数器值为空. b.JVM栈(Java Virtual Machine Stack) 描述Java方法执行的内存模型,每个方法在执行的同时都会创建一个栈帧(Stacks Frame)用于存储局部变量表,操作数栈,动态链接,方法出口等信息. 每一个方法从调用直至执行完成