JVM运行时内存划分

本文详细介绍了JVM的运行时数据区域,包括程序计数器、虚拟机栈、本地方法栈、堆、方法区(含运行时常量池)等。每个区域的作用、数据结构以及线程私有和线程共享的区别都进行了阐述,还涉及到了对象创建过程、内存分配策略以及类加载器的工作原理。文章深入讲解了类加载的加载、验证、准备、解析、初始化五个阶段,以及双亲委派模型在类加载中的应用。
摘要由CSDN通过智能技术生成
一、运行时数据区域
    JVM在执行java程序的过程中会把他所管理的内存划分为若干个不同的数据区域。这些区域有各自的创建和销毁的时间,这些区域可分为线程私有和共有两类, 线程私有的有: 程序计数器java虚拟机栈本地方法栈线程公有的有: 方法区。如图所示:
1、程序计数器(线程私有)
也就是 字节码的行号指示器模拟的是CPU的程序计数器), 指示 当前进程 所要执行的字节码(而不是下一条),这个指令将交给 字节码解释器去完成解释功能。
因为要保证线程切换后能恢复到正确的执行位置,每条线程都需要有个独立的程序技术器,各条程序计数器之前互不影响,独立存储。所以他是“ 线程私有的”。 如果一个线程正在执行一个java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是本地方法,这个计数器值为null
 
2、java虚拟机栈(线程私有)
描述的是 java方法执行的内存模型栈中存储的是一个一个的 栈帧 每个方法在执行的同时都会创建一个栈帧),而一个方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。
栈帧: 存储局部变量表(方法中的局部变量)、操作数栈、动态链接、方法出口等信息。
1、局部变量表
用来存储方法参数和方法内部定义的局部变量。 【包括:8种基本数据类型、对象引用(eference)和returnAddress()】。局部变量表的容量是以 变量槽 为最小单位的。 其中long和double会占用两个局部变量空间,其余的只占1个空间 局部变量表所需要的内存空间在编译期已经完成分配 。局部变量表中的变量使用之前必须赋予初始值,不想类变量有两次赋初始值的过程(一次在准备阶段,赋予系统初始值;一次在初始化阶段,赋予程序员定义的值)
 
2、操作数栈
操作数栈的每一个元素可以是任意Java数据类型,32位数据类型所占的栈容量为1字宽,64位数据类型所占的栈容量为2字宽。对于32位虚拟机来说,一个”字宽“占4个字节,对于64位虚拟机来说,一个”字宽“占8个字节。
当一个方法刚刚执行的时候,这个方法的操作数栈是空的,在方法执行的过程中,会有各种字节码指向操作数栈中写入和提取值
另外,在概念模型中,两个栈帧作为虚拟机栈的元素,相互之间是完全独立的,但是大多数虚拟机的实现里都会作一些优化处理,令两个栈帧出现一部分重叠。 让下栈帧的部分操作数栈与上面栈帧的部分局部变量表重叠在一起 ,这样在进行方法调用返回时就可以共用一部分数据,而无须进行额外的参数复制传递了,重叠过程如下图:
 
3、动态链接
每个栈帧都包含一个指向运行时常量池 (方法区中的一部分空间,用来存储各种字面量和符号的引用)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值