1运行时数据区

2018-08-26 17:18:37来源:博客园 阅读 ()

新老客户大回馈,云服务器低至5折

先来张图:

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

为什么指向正在执行的字节码指令的地址?因为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),下一篇。

 

 

 

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:自动拆装箱

下一篇:interface21 - web - Log4jConfigListener(Log4j加载流程)