常量池在堆还是方法区_JVM运行时数据区总结

引言

我们知道,JAVA的平台无关性离不开JVM,使得JAVA代码与计算机硬件和 操作系统解耦。关于JVM,贯穿了JAVA编译、执行、优化等方方面面,今天,我们先来看看JVM有哪些区域组成。

运行时数据区

背一下:堆、栈(虚拟机栈、本地方法栈)、程序计数器、方法区(包含常量池)。除此之外还有本地方法接口和方法库,让方法跑起来的执行引擎。

这些都是干嘛的,怎么运作的?

堆:存对象用的,我们new出来的对象存在这里,占据虚拟机内存的半壁江山。在jdk7之后,字符串的常量池也被移到堆中(其他常量池还在方法区)。正因为堆占得内存大,所以是垃圾回收的主要对象,毕竟收益更加明显。提到垃圾,就想到了垃圾分类,没错,JVM也搞垃圾分类。这个我们在第二节讲。

栈:栈,大家都不陌生,stack,后进先出。是的,JVM采用的就是基于栈的执行引擎,就是方法的执行时基于栈操作的,如代码 a + b,你可能会看到类似操作,iload_1;iload_2;iadd;不一定完全一致,但表达的意思是将a和b陆续压栈,执行add操作,并将操作结果放入栈顶。

另外:就是栈帧,它是java方法执行的基本单位,执行一个方法就是一个栈帧,栈帧里面就包含方法用到的 局部变量表、操作栈、方法在常量池的引用、返回地址。

虚拟机栈和本地方法栈是类似的。

程序计数器(PC):记录线程方法的执行行号。因为每个线程在执行过程中,可能会访问磁盘IO等,当结束的时候需要接着从哪继续执行,所以记录线程执行到的位置是有必要的。就行你平时看书插个书签一样。还有类似跳转、异常、循环等,接下来执行的代码是需要有一个标识的。

栈和程序计数器是线程私有的,很好理解,每个线程都会并发(多核cpu还会并行)执行不同的方法,在一个虚拟机栈上无法满足需求,且无法搞清楚谁是谁的方法。既然栈是每个线程一个,PC当然是人手一个。另外,在执行本地方法的过程中,PC记录的行号为空,因为它不知道本地方法是怎样的,真因为如此,在执行本地方法的时候,不会发生线程切换吧?否则当轮到cpu时间片时,又怎么知道从哪里继续执行呢!

方法区:就是“存方法信息的地方”,相比它的字面义,它存的东西还更多,加载后的类信息、常量(final)、静态常量(static)、JIT编译后的机器码都存在方法区,其中主要关注的是:常量池。常量池中包含的信息很多,类定义,方法定义,字段定义的等引用都存在常量池中。

本地方法接口和本地库:这个主要大概了解一下JAVA有很多操作是调用C++编写的类库的(native方法),比如UnSafe类,这部分就是本地方法。

执行引擎:前面也说了,JVM采用的是基于栈的执行引擎,相对的还有"基于寄存器的执行引擎",两个各有优缺点,比如基于栈是基于内存的,可移植性较强,但性能低一些。基于寄存器的与硬件关联度较高,不利于移植等。

讲了那么多,我们串联起来讲一下

举个例子:

class User{

public final static String hello = "HELLO WORLD";

private String name;

public String getName() {

return name;

}

public static void main(String[] args){

User user = new User();

user.getName();

}

}

执行这段代码是一个大概怎样的过程:

首先是javac编译,也叫前端编译,是将*.java文件编译为*.class字节码文件的过程。字节码文件是一个符合虚拟机规范,格式规整的字节码文件,这里就涉及到编译原理的知识了(词法分析、语法分析生成AST、语义分析、校验、解语法糖等操作)。

类加载,将生成的字节码文件加载到JVM中,这里就涉及到classLoader的相关知识(如双亲委派模型,SPI等),加载的过程会涉及到验证,解析,类的初始化(clinit),把类中的常量、方法引用、类的引用放到方法区。

执行,这里就开始执行代码了,java是解释执行的语言(当然也有编译执行JIT的帮助),当遇到new 的字节码时,执行引擎就会在堆中开辟一块空间(涉及指针碰撞、空闲列表等),并初始化(对象头不初始化)。堆中生成的对象仍然会保留着对方法区类,常量的引用。而执行方法的时候就是基于栈的操作,前面也有提到。

简单点说大概就是这样,有一个大概的概念。

说的有什么问题,欢迎指点。

————————————————

d43d8250692cdb7c5e9eec4a995a0767.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值