Java虚拟机学习(一)-运行时数据区

作为一个Java程序员,如果要深入学习Java的话,那么了解Java虚拟机是必不可少的。通过学习Java虚拟机的知识,我们不仅可以了解Java的运行原理,而且也可以加深对Java编程的理解。
以前总觉得Java虚拟机是一种神秘的存在,理解起个肯定不容易,但是一些前辈确很推荐去学习一下。所以现在就计划开始学习Java虚拟机。在此,以博客的形式记录一下学习笔记和心得。
今天记录一下Java虚拟机运行时数据区。
在Java虚拟机中内存分为若干个数据区,我们经常说的有Java堆,Java虚拟机栈,除此之外还有程序计数器(也称PC寄存器),方法区,运行时常量池以及本地方法栈。接下来就记录一下这些数据区的作用和介绍。

程序计数器,也可以说是PC寄存器。
1.访问权限:线程所有;
2.作用:记录线程中执行方法的位置;
程序计数器是一块较小的内存,用来记录线程执行字节码指令的位置,没执行一条指令,程序计数器就会加1(这个1是指一个单位长度)。由于Java虚拟机是多线程的,而在任意时刻,在Java虚拟机中的线程只能执行一个方法,所以在线程切换时,线程可以根据程序计数器找到正确的执行位置。

Java虚拟机栈
1.访问权限:线程私有
2.作用:存储栈帧;
Java虚拟机栈是属于线程私有的,线程创建时Java虚拟机栈也随之创建,线程结束时,Java虚拟机栈也被释放。在方法执行的时候会创建一个栈帧存储于Java虚拟机栈用于存储局部变量、操作数栈、动态链接、方法出口以及一些过程结果等。每一个方法从调用直至执行完成的过程,就对应着一个栈帧在Java虚拟机栈中的出栈和入栈的过程。

Java堆
1.访问权限:线程共享
2.作用:存放对象实例(类实例、数组对象等)
Java堆也就是GC堆,垃圾收集器就是用来管理Java堆的。Java堆在虚拟机启动时创建,用来存放对象实例和数组对象。在Java堆中的对象不用使用者主动销毁,这就是内存管理系统。
参数配置:-Xmx -Xms

方法区
1.访问权限:线程共享
2.作用:存储类的结构信息(运行时常量池、字段、方法数据)
方法区在虚拟机启动时创建。在Java虚拟机规范中,方法区是Java堆的一个逻辑部分,但是方法区在可以选择不实现垃圾收集。相对而言,垃圾收集在方法区很少出现,但这部分区域的数据也不是永远存在,方法区主要针对常量池的回收和类型的卸载

运行时常量池
1.访问权限:属于方法区
2.作用:存放编译器生成的字面量、符号引用等
运行时常量池是类或接口的常量池在运行时的一种表现形式,它包括了从编译期可知的数值字面量和到运行期解析后才能获得的方法或字段引用。也就是说常量不仅仅是在编译期才能产生,在运行时也可以有新的常量。比如String的intern方法就是如果在常量池中有相应的字面量则返回没有就加入常量池。

本地方法栈
本地方法栈主要服务于native方法。在Java虚拟机规范中没有规定本地方法栈所使用的语言,可以由虚拟机去实现。

栈帧
栈帧属于Java虚拟机栈,用来存储数据和部分过程的结果,同时也用来处理动态链接、方法返回值和异常处理。
栈帧随着方法的调用而创建,随着方法的结束而销毁。在Java虚拟机中每个线程在同一时刻只能执行一个方法,每个方法里面存在一个活动的栈帧。当前方法调用另外方法是启动一个新的栈帧,当方法返回时回到前一个栈帧,方法结束栈帧结束。每个栈帧都保有自己的局部变量表、操作数栈和指向当前方法所属类的运行时常量池的引用。

1.局部变量表:每个栈帧内部都包含一组称为局部变量表的变量列表。栈
帧中局部变量表的长度由编译期决定,并且存储于类和接口的二进制表示之中,既通过方法的Code 属性保存及提供给栈帧使用。一个局部变量可以保存一个类型为 boolean、byte、char、short、float、reference
和 returnAddress 的数据,两个局部变量可以保存一个类型为 long 和 double 的数据。

2.操作数栈:每一个栈帧内部都包含一个称为操作数栈的后进先出栈。栈帧中操作数栈的长度由编译期决定,并且存储于类和接口的二进制表示之中,既通过方法的 Code 属性保存及提供给栈帧使用。操作数栈所属的栈帧在刚刚被创建的时候,操作数栈是空的。Java 虚拟机提供一些字节码指令来从局部变量表或者对象实例的字段中复制常量或变量值到操作数栈中,也提供了一些指令用于从操作数栈取走数据、操作数据和把操作结果重新入栈。在方法调用的时候,操作数栈也用来准备调用方法的参数以及接收方法返回结果。

3.动态链接:每一个栈帧内部都包含一个指向运行时常量池的引用来支持当前方法的代码实现动态链接。在 Class 文件里面,描述一个方法调用了其他方法,或者访问其成员变量是通过符号引用来表示的,动态链接的作用就是将这些符号引用所表示的方法转换为实际方法的直接引用。类加载的过程中将要解析掉尚未被解析的符号引用,并且将变量访问转化为访问这些变量的存储结构所在的运行时内存位置的正确偏移量。

4.方法返回:栈帧负责方法调用返回,包括正常返回和异常返回。当方法正常返回时,栈帧负责通知调用者相关状态变化(局部变量表、操作数栈和被正确增加过来表示执行了该方法调用指令的程序计数器等)。当方法异常返回时,方法中没用处理该异常,调用者也无法获得正确的返回值。

Java虚拟机的数据区域就大致分为者几块。一个Java程序能够顺利的运行就是通过各个数据区的相互协调完成的。学习Java虚拟机的数据区,我们就能够对程序运行时的一些调度理解的更加透彻。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值