jvm认识与探究(二)运行时数据区

官网概括:https://docs.oracle.com/javase/specs/jvms/se8/html/index.html

一、总体认识

Java虚拟机定义了在程序执行期间使用的各种运行时数据区域。其中一些数据区域是在Java虚拟机启动时创建的,只有在Java虚拟机退出时才会销毁。其他数据区域是每个线程。每个线程的数据区域在线程创建时创建,在线程退出时销毁。

在这里插入图片描述

1.方法区

a.方法区是各个线程共享的内存区域,在虚拟机启动时创建。
b.用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
c.方法区包含运行时常量池(Run Time Constant Pool),用于存放编译时期生成的各种字面常量和符号引用。
d.方法区在JDK8就是Metaspace,在JDK7中就是Perm Space

2.堆

a.Java堆是Java虚拟机所管理内存中最大的一块,在虚拟机启动时创建,被所有线程共享。
b.用于存放对象实例和数组。

3.虚拟机栈

a.每个Java虚拟机线程都有一个私有的Java虚拟机堆栈,与线程同时创建,每个线程独有。
b.每一个被线程执行的方法,为该栈中的栈帧,即每个方法对应一个栈帧。
c.调用一个方法,就会向栈中压入一个栈帧;一个方法调用完成,就会把该栈帧从栈中弹出。

在这里插入图片描述

4.本地方法栈

a.如果当前线程执行的方法是Native类型的,这些方法就会在本地方法栈中执行。

5.程序计数器

a.程序计数器占用的内存空间很小,由于Java虚拟机的多线程是通过线程轮流切换,并分配处理器执行时间的方式来实现的,在任意时刻,一个处理器只会执行一条线程中的指令。因此,为了线程切换后能够恢复到正确的执行位置,每个线程需要有一个独立的程序计数器记录执行方法的位置,线程独有。
b.如果线程正在执行Java方法,则计数器记录的是正在执行的虚拟机字节码指令的地址。
c.如果正在执行的是Native方法,则这个计数器为空。

二、结合字节码文件理解jvm栈和栈帧

官方说明:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.6

每个栈帧中包括局部变量表(Local Variables)、操作数栈(OperandStack)、指向运行时常量池的引用(A reference to the run-time constant pool)、方法返回地址(Return Address)和附加信息。

局部变量表
方法中定义的局部变量以及方法的参数存放在这张表中,局部变量表中的变量不可直接使用,如需要使用的话,必须通过相关指令将其加载至操作数栈中作为操作数使用。
操作数栈
以压栈和出栈的方式存储操作数的。
动态链接:
每个栈帧都包含一个指向运行时常量池中该栈帧所属方法的引用,持有这个引用是为了支持方法调用过程中的动态连接(Dynamic Linking)。例如:多态则使用到动态链接。
方法返回地址
当一个方法开始执行后,只有两种方式可以退出,一种是遇到方法返回的字节码指令;一种是遇见异常,并且 这个异常没有在方法体内得到处理。

在这里插入图片描述
User.java源代码

class User{
	private String name;
	private Integer age;
	private Integer sex;
	
	public int calc(int op1, int op2){
		op1 = 3;
		int result = op1 + op2;
		return result;
	}
}

查看User.class文件

Compiled from "User.java"
class User {
  ......
  public static int calc(int, int);
    Code:
       0: iconst_3	//将int常量3压入【操作数栈】
       1: istore_0	//将int类型值存入【局部变量0】
       2: iload_0	//从【局部变量0】中装载int类型值入栈
       3: iload_1	//从【局部变量0】中装载int类型值入栈
       4: iadd		//将栈顶元素弹出栈,执行int类型的加法,结果入栈
       5: istore_2	//将栈顶int类型值保存到【局部变量2】中
       6: iload_2	//从【局部变量2】中装载int类型值入栈
       7: ireturn	//从方法中返回int类型的数据
}

局部变量表:op1、op2、result
操作数栈:10、3

参照官网字节码指令说明:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iconst_i

三、Java对象内存布局

一个对象在内存中包括三个部分:对象头、实例数据、对齐填充

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值