JVM-运行时数据区-超详细让你轻松掌握

概述:

运行时数据区,Java虚拟机(JVM)中用于存储程序运行期间所需的各种数据的内存区域。主要包括程序计数器,java虚拟机栈,本地方法栈,堆,方法区。

1. 线程不共享

(1)程序计数器

      a. 定义

        记录当前要执行的的字节码指令的地址

        b. 内容

        类加载器将字节码加载到内存后,会将原文件中的偏移量转换成内存地址。每一条字节码指令都会拥有一个内存地址。代码执行时,程序计数器会记录下一行字节码指令的地址。

注:由于程序计数器存储固定长度的内存地址,因此不会出现内存溢出。

(2)虚拟机栈

       a. 定义

        采用栈的数据结构来管理方法调用中的基本数据,每个方法的调用链会压入一个栈中,执行时先进后出(FILO)。

       b. 组成

            1) 局部变量表

                      局部变量表中保存了实例方法的this对象,方法参数,局部变量。

            2) 操作数栈

                      字节码指令执行过程中用来存放中间数据的一块区域,是一种栈式结构。

                      将局部变量表中对应索引位的值加载到操作数栈中进行计算,然后将得到的值再保存到局部变量表中对应索引位中。

            3) 帧数据

                帧数据主要包含动态链接、方法出口、异常表的引用。

                动态链接:字节码中的符号引号到运行时常量池的内存地址的映射关系。

                方法出口:方法执行完后,程序计数器将指向下一条将要执行的字节码指令的地址。

                 异常表:存放代码中异常的处理信息。

注:java虚拟机栈会出现内存溢出StackOverFlowError,常见的如:递归调用

可以通过-Xss来指定栈的大小

(3)本地方法栈

          本地方法栈结构与虚拟机栈类似,服务于本地方法,管理本地方法执行所需的数据。

2. 线程共享

(1)堆

          a. 定义

        存储对象的内存区域,堆内存是线程共享的。分为年轻代与老年代,年轻代又分为伊甸园区和存活区。

          可以通过-Xmx设置堆内存的最大值,通过-Xms设置堆内存的初始值。

注:堆内存会出现内存溢出OutOfMemoryError: Java heap space。设置堆内存大小时,建议将-Xmx与-Xms设置成一样的值,这样可以减少扩容的开销。

(2)方法区

        a. 定义

                用于存储每个类的元信息,运行时常量池,字符串常量池。

        b. 组成

        类的元信息:包括类的基本信息,接口,字段,方法,属性。在类的字节码被类加载器加载到方法区时,会在方法区中创建一个instanceKlass的对象,该对象还会包含方发表,方发表是实现多态的基础。

        运行时常量池:字节码中常量池成为静态常量池,通过符号引用进行常量查找。在字节码被加载到方法区后,静态常量池会变成运行时常量池,符号引用会变成内存地址,通过内存地址查找常量。

        字符串常量池:存储代码中定义的常量字符串内容。

注:JDK7之前,方法区存储在堆的永久代中,字符串常量池存储在方法区。JDK7时,字符串常量池从方法区中移到了堆中。JDK8时,方法区移到了元空间中,即直接内存中。方法区会出现内存溢出,OutOfMemoryError:MetaSpace。

             

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值