1运行时数据区
2018-08-26 17:18:37来源:博客园 阅读 ()
先来张图:
一、程序计数器:指向当前线程正在执行的字节码指令的地址(或者说行号)。每个线程都有一个自己的计数器。
为什么指向正在执行的字节码指令的地址?因为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
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- Java中Error和Exception的异同以及运行时异常(Runtime exce 2020-05-13
- Java 虚拟机中的运行时数据区分析 2020-04-26
- JVM系列十三(运行时栈帧结构). 2020-04-20
- java笔记----运行时程序代码定位 2020-04-08
- JVM学习(3):运行时数据区 2020-03-12
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash