JAVA内存模型之运行时数据区

我们都知道JVM有3大核心:类加载系统,运行时数据区,字节码执行引擎。

前面的文章主要是说到类加载系统,今天这个文章我们来说一说运行时数据区。

运行时数据区在jvm内存模型里面占到非常重要的地位。

整体如下图所示:

 如上面图所示,运行时数据区被分为5个部分:堆,栈,本地方法栈,方法区,程序计数器。

下面我们就详细说一下这5个部分:

:一般情况下new对象都是在堆上面 jvm的栈(线程)里面放的可能就是运行的线程的局部变量(栈是first in last out),每一个线程都会在内存中开辟自己的栈内存 (每一个线程里面方法都有一个栈帧)。

:主要存放的为局部变量,但是如果这个局部变量类型为对象的话,此时栈里面存的就是对象指向堆里面的地址。

  栈详解:当java程序开始运行主线程的时候(我们暂且理解为main方法),Java虚拟机就会在栈内存的大片空间给当前方法分配一块独立的内存空间用来放当前线程执行过程中用到的局部变量

有图有真相:

     如上图所示:jvm在调用main方法的时候会在栈里面开辟一个小的内存空间(栈桢保存局部变量),然后执行mian方法调用compute()方法的时候,还会再开辟一个小的内存空间(栈桢),每一次开辟都是向上累加的过程。也就是说调用一次方法就会开辟一块栈帧空间,每次拿元素的时候只能从栈顶拿(符合栈的数据结构:先进去后出)。栈里面的数据结构和栈的数据结构是一样的(为什么?这个和代码的执行顺序基本上是一致的) 执行完出栈销毁空间。 默认的方法栈的大小1M。

     栈内部结构 :每一个方法对应一个栈帧内存空间(比如一个mian方法对于一个线程栈 而main方法里面还有很多方法 每一个方法都会有一个栈帧)

       栈内部结构主要有:局部变量表 操作数栈 动态链接 方法出口。

       比如上面的程序图中 先将a,b压入局部变量表中 当执行a+b的时候 再将a,b压入操作数栈 最后将a+b的值压入操作数栈,将我们定义的局部变量先压入操作数栈,然后再局部变量表中申请空间再次压入局部变量表中 依次重复 最后将结果irLoad执行+和-等操作是到cpu寄存器里面做计算的。

说到这里就不得不提到3个概念:

操作数栈:存的是程序运行时需要操作的局部变量临时的一块内存空间。

动态链接:是在程序运行的过程中将符号引用转为直接引用的地址。

静态链接:是在程序加载的过程中将符号引用转为直接引用的地址。

符号表示程序里面的方法名称、()等等,当程序运行到这个符号的时候需要解析(说明当程序运行的时候静态方法会去解析(静态链接),但是自己定义的方法将不会去解析) 就是找到符号对应的指令可以总结引用具体的地址。比如mian方法里面还有一个局部变量表 存入的math ----> math存入的是new在堆里面math对象的地址

本地方法栈:是 在java里面基本上是用C语言写的 很多的native修饰的方法(比如synchorized) 在Java里面有很多是调用c或者c++ 就是在jar包里面的.dll文件

方法区:有的人也叫元空间,在jdk1.8之前叫持久代,1.8后叫元空间,其实方法区就是jvm定义的一个抽象的概念,具体的实现是由持久代或者元空间实现的 元空间在jdk1.8之后使用的是直接内存空间(不去占用java虚拟机的内存空间 使用的是物理内存空间(内存条)) 可以将方法区理解为存代码信息的地方。

     同时我们也需要知道元空间默认大小为21M,当对象的大小超过这个值就会触发full Gc,在jdk1.8的时候对元空间进行优化。

       方法区容量大小自动扩容机制: 假如这次full gc 将原来方法区里面的21M垃圾回收到还有1M回收不了,就会将方法区的容量调小, 如果回收还有18M回收不了了,可能就会将方法区容量调大,也就是小次触发full gc的水平线可能变成30M或者40M

程序计数器:记录jvm正在执行代码的位置(也是每一个线程都有一个)标志着jvm将要执行的行数 ,程序每执行一行程序计数器都会被修改而这个修改是由jvm的字节码执行引擎来做的 因为java多线程 所以设定了这个程序计数器。

jvm内存模型里面:栈,程序计数器是每一个线程独享的,而堆,方法区是所有的线程共享的 共用物理机的内存(内存条)

JVM内存模型Java虚拟机在运行所使用的内存分配和管理方式。它包括了运行数据区,也就是JVM在内存中划分的不同区域,用来存储程序的数据和指令。 JVM运行数据区主要包括以下几个部分: 1. 堆(Heap):用于存储对象实例和数组。堆是线程共享的区域,所有线程共同使用堆来创建和访问对象。 2. 方法区(Method Area):用于存储已加载的类信息、常量、静态变量和编译后的代码等。方法区也是线程共享的区域,它在内存中占用一块连续的空间。 3. 虚拟机栈(VM Stack):每个线程在创建都会分配一个虚拟机栈,用来存储局部变量和方法调用信息。虚拟机栈是线程私有的,每个线程都有自己独立的虚拟机栈。 4. 本地方法栈(Native Method Stack):与虚拟机栈类似,用于存储本地方法调用的相关信息。 5. 程序计数器(Program Counter Register):用于存储当前线程执行的字节码指令的地址。 这些不同的运行数据区JVM内存模型中起着不同的作用,可以提供给程序运行所需的各种资源和环境。例如,堆用于存储对象实例,方法区用于存储类信息和静态变量,虚拟机栈用于存储方法的局部变量和方法调用信息等。 总的来说,JVM内存模型运行数据区Java虚拟机在运行所使用的内存管理和分配方式。它们的不同区域有不同的作用,用来存储程序的数据和指令。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [运行数据区JVM内存模型](https://blog.youkuaiyun.com/weixin_45659364/article/details/124027073)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [JVM:Java内存模型运行数据区域](https://blog.youkuaiyun.com/m0_71777195/article/details/131655107)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [Java内存模型JVM运行数据区的区别详解](https://download.youkuaiyun.com/download/weixin_38648037/12745990)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值