当前位置: 移动技术网 > IT编程>开发语言>Java > 1运行时数据区

1运行时数据区

2018年08月23日  | 移动技术网IT编程  | 我要评论

先来张图:

一、程序计数器:指向当前线程正在执行的字节码指令的地址(或者说行号)。每个线程都有一个自己的计数器。

为什么指向正在执行的字节码指令的地址?因为cpu会切换线程执行,当前线程可能会被挂起,被挂起的时候当前指令可能没执行完成,待cpu重新调度到该线程时,需要知道当前线程执行到哪了。

二、虚拟机栈:存储当前线程运行方法所需要的数据,指令和返回地址。(---->栈---->数据结构----->存储数据---->存什么数据?)

 

 

虚拟机描述的是java方法执行的内存模型:每个方法执行时会创建一个栈帧。栈帧的结构大致如下:(网上找来的图)

 

1.局部变量表:用于存放方法参数和方法内部定义的局部变量。(大小在编译时已经确定)

局部变量表以变量槽(slot)为 最小单位,boolean,byte,char,short,float,reference或returnaddress占一个slot,

long ,double占两个slot。

 举个例子:(某视频上的)

 1 public class helloworlddemo {
 2     // 常量、静态变量
 3     private final int i = 0;
 4     private static int k = 0;
 5     //成员变量
 6     private object obj=new object();
 7     private int sss=0;
 8     
 9     //局部变量
10     public void methodone(int i) {
11         int j=0;
12         int sum=i+j;
13         object acb=obj;
14         long start = system.currenttimemillis();
15         methodtwo();
16         return;
17     }
18 
19     public static void methodtwo() {
20         methodtwo();
21     }
22     public static void main(string[] args) {
23         methodtwo();
24     }
25 }

使用javap -c -v 命令反编译其class文件,可以看到methodone方法各变量在局部变量表的位置:

可以看出:this在0位置,i,j,sum等分别在1,2,3位置。(非静态方法0位置是this)

2.操作数栈:通常称为操作栈(后入先出),栈的最大深度在编译时已确定。

网上搜索了解methodone大概执行流程:

public void methodone(int);
descriptor: (i)v
flags: acc_public
code:
stack=2, locals=7, args_size=2
0: iconst_0 //将int类型常量0压入栈(虚拟机栈)
1: istore_2 //将int类型值存入局部变量2 (即程序中的j)(此时0会出栈)
2: iload_1 //从局部变量表1中装载int类型值(即i的值)(i值入栈)
3: iload_2 //从局部变量表2中装载int类型值(即j的值)(j值入栈)
4: iadd //执行add操作
5: istore_3 //将结果存入局部变量表3 (即sum)(结果出栈)
6: aload_0 // 将第一个引用类型本地变量推送至栈顶(非静态方法是this,静态方法是第一个引用类型变量)
7: getfield #25 // field obj:ljava/lang/object; //将栈顶的指定的对象的第25个实例域(field)的值(6到7不是很明白,this的值,按流程aload_0应该指的是obj这个对象)
(这个值可能是引用,这里就是引用)压入栈顶
10: astore 4 //将栈顶的值存入局部变量4 (即acb)
12: invokestatic #33 // method java/lang/system.currenttimemillis:()j //调用类的static方法
15: lstore 5 //将栈顶long型数值存入局部变量表5中(即start)
17: invokestatic #39 // method methodtwo:()v //调用本类static方法methodtwo()
20: return
linenumbertable:
line 13: 0
line 14: 2
line 15: 6
line 16: 12
line 17: 17
line 18: 20
localvariabletable:
start length slot name signature
0 21 0 this lcom/thomas/jvm/helloworlddemo;
0 21 1 i i
2 19 2 j i
6 15 3 sum i
12 9 4 acb ljava/lang/object;
17 4 5 start j

 

3.动态链接:运行时才确定真正的链接。比如在类内声明接口类型的变量  private  iusb usb;在方法内调用其do方法时,实际调用的是其具体某个实现类的do方法,这是在运行时才需要确定的,假如方法不执行就不必知道。

4.返回地址:出栈后去哪?返回地址确定

递归调用时有多少个栈帧?n个    递归会导致stackoverflowerror

三、本地方法栈:描述的是本地方法出栈入栈的过程,类比于虚拟机栈。native方法:简单的说,就是一个java调用非java代码的接口。

四、方法区:存储类信息,常量(1.7)静态变量,jit(即时编译器)编译后的代码(动态代理,在jvm运行时生成的代码,也要加载到内存中)。

五、heap(堆):存放对象实例。这里涉及到jvm内存模型(jmm),下一篇。

 

 

 

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网