【JVM】运行时数据区、程序计数器

简介: 【JVM】运行时数据区、程序计数器

JVM

类加载器将字节码文件加载到内存当中的时候,会用到两块内存区域:一块是方法区、另外一块叫做堆区,这两块区域都属于Java虚拟机管理的内存,由于JVN在运行过程中会去使用这块内存,所以就称之为运行时数据区域,它的职责除了保存字节码信息之外,还可以将创建出来的对象放到这块内存区域。

一、 运行时数据区

通常把运行时数据区换分为两类,一类是线程不共享(程序计数器、Java虚拟机栈、本地方法栈)、一类是线程共享(方法区、堆区)

  • 线程不共享指的是每当创建一个线程之后,每个线程里都会有一份程序计数器、Java虚拟机栈和本地方法栈对应的数据,该数据由本线程维护,其他线程无法访问本线程对应的数据,所以数据无法做到共享,但是整体安全性比较高,当线程结束后,将整个线程回收掉,这块内存区域也会得到释放。
  • 线程共享指的是只要往方法区/堆区放入数据,每个线程都可以获取这些数据并去使用,虽然数据可以共享,但是存在安全性问题

二、 程序计数器

程序计数器(Program Counter Register)也叫PC寄存器,每个线程会通过程序计数器记录当前要执行的的字节码指令的地址。

  • 属于线程独自拥有的数据,里面存放了接下来要执行的字节码指令的内存地址。
  • 字节码指令最初是保存在字节码文件中的,类加载器把字节码文件读取到内存之后,这个指令也会保存到内存当中,每一行指令都有对应的内存地址。
  • 字节码指令最终是要被解释器解释执行的,所以解释器就需要知道要执行的字节码指令在哪,而程序计数器就恰恰保存了字节码指令的地址,解释器只需要通过程序计数器就能得到字节码指令的内存地址。

程序计数器的案例

  • 源代码
public static void main(String[] args) {
        int i = 0;
        if (i == 0) {
            i--;
        }
        i++;
    }
  • 字节码指令
0 iconst_0
1 istore_1
2 iload_1
3 ifne 9 (+6)
6 iinc 1 by -1
9 iinc 1 by 1
12 return

将局部变量 i 赋值为0

  • iconst_0
  • istore_1

判断 i 和0是否相等,如果不相等,跳转到指令9的位置

  • iload_1
  • ifne 9 (+6)

i 和 0 相等,就将i减1:

  • iinc 1 by -1

i 和 0 不相等,就将 i 加1:

  • iinc 1 by 1

接下来这个字节码指令就会进入类的加载阶段被加载到内存中,原来字节码指令的每条指令前都有一个偏移量,加载到内存后,偏移量会被替换成地址,每一条字节码指令都会有自己的内存地址,在代码执行过程中,程序计数器会记录下一行字节码指令的地址。执行完当前指令之后,虚拟机的执行引擎根据程序计数器执行下一行指令。

程序计数器可以控制程序指令的进行,实现分支、跳转、异常等逻辑。

在多线程执行情况下,Jva虚拟机需要通过程序计数器记录CPU切换前解释执行到那一句指令并继续解释运行。


相关文章
|
5月前
|
存储 安全 Java
JVM深入原理(七)(一):运行时数据区
栈的介绍:Java虚拟机栈采用栈的数据结构来管理方法调用中的基本数据,先进后出,每一个方法的调用使用一个栈帧来保存栈的组成:栈:一个线程运行所需要的内存空间,一个栈由多个栈帧组成栈帧:一个方法运行所需要的内存空间活动栈帧:一个线程中只能有一个活动栈帧栈的生命周期:栈随着线程的创建而创建,而回收会在线程销毁时进行栈的执行流程:栈帧压入栈内执行方法执行完毕释放内存若方法间存在调用,那么会压入被调用方法入栈,执行完后释放内存,再执行当前方法,直到执行完毕,释放所有内存。
83 0
|
5月前
|
存储 缓存 安全
JVM深入原理(七)(二):运行时数据区
堆的作用:存放对象的内存空间,它是空间最大的一块内存区域.栈上的局部变量表中,可以存放堆上对象的引用。静态变量也可以存放堆对象的引用,通过静态变量就可以实现对象在线程之间共享。堆的特点:线程共享:堆中的对象都需要考虑线程安全的问题垃圾回收:堆有垃圾回收机制,不再引用的对象就会被回收方法区的概述:方法区是存放基础信息的位置,线程共享,主要包括:类的元信息:保存了所有类的基本信息运行时常量池:保存了字节码文件中的常量池内容静态常量池:字节码文件通过编号查表的方式找到常量。
70 0
|
7月前
|
存储 Java C++
JVM 运行时数据区
Java 虚拟机在执行 Java 程序的过程中会把它所管理的内存区域划分为若干个不同的数据区域。这 些区域都有各自的用途,以及创建和销毁的时间,有些区域随着虚拟机进程的启动而存在,有些区 域则是依赖线程的启动和结束而建立和销毁。Java 虚拟机所管理的内存被划分为如下几个区域 程序计数器(Program Counter Register):当前线程所执行的字节码的行号指示器,字节码解 析器的工作是通过改变这个计数器的值,来选取下一条需要执行的字节码指令,分支、循环、跳 转、异常处理、线程恢复等基础功能,都需要依赖这个计数器来完成; 为什么要线程计数器?因为线程是不具备记忆功能 Java 虚拟机
|
5月前
|
Arthas 存储 算法
深入理解JVM,包含字节码文件,内存结构,垃圾回收,类的声明周期,类加载器
JVM全称是Java Virtual Machine-Java虚拟机JVM作用:本质上是一个运行在计算机上的程序,职责是运行Java字节码文件,编译为机器码交由计算机运行类的生命周期概述:类的生命周期描述了一个类加载,使用,卸载的整个过类的生命周期阶段:类的声明周期主要分为五个阶段:加载->连接->初始化->使用->卸载,其中连接中分为三个小阶段验证->准备->解析类加载器的定义:JVM提供类加载器给Java程序去获取类和接口字节码数据类加载器的作用:类加载器接受字节码文件。
480 55
|
6月前
|
Arthas 监控 Java
Arthas memory(查看 JVM 内存信息)
Arthas memory(查看 JVM 内存信息)
459 6
|
9月前
|
存储 设计模式 监控
快速定位并优化CPU 与 JVM 内存性能瓶颈
本文介绍了 Java 应用常见的 CPU & JVM 内存热点原因及优化思路。
929 166
|
11月前
|
缓存 Prometheus 监控
Elasticsearch集群JVM调优设置合适的堆内存大小
Elasticsearch集群JVM调优设置合适的堆内存大小
1809 1
|
7月前
|
存储 缓存 算法
JVM简介—1.Java内存区域
本文详细介绍了Java虚拟机运行时数据区的各个方面,包括其定义、类型(如程序计数器、Java虚拟机栈、本地方法栈、Java堆、方法区和直接内存)及其作用。文中还探讨了各版本内存区域的变化、直接内存的使用、从线程角度分析Java内存区域、堆与栈的区别、对象创建步骤、对象内存布局及访问定位,并通过实例说明了常见内存溢出问题的原因和表现形式。这些内容帮助开发者深入理解Java内存管理机制,优化应用程序性能并解决潜在的内存问题。
327 29
JVM简介—1.Java内存区域
|
7月前
|
缓存 监控 算法
JVM简介—2.垃圾回收器和内存分配策略
本文介绍了Java垃圾回收机制的多个方面,包括垃圾回收概述、对象存活判断、引用类型介绍、垃圾收集算法、垃圾收集器设计、具体垃圾回收器详情、Stop The World现象、内存分配与回收策略、新生代配置演示、内存泄漏和溢出问题以及JDK提供的相关工具。
JVM简介—2.垃圾回收器和内存分配策略
|
7月前
|
存储 设计模式 监控
如何快速定位并优化CPU 与 JVM 内存性能瓶颈?
如何快速定位并优化CPU 与 JVM 内存性能瓶颈?
171 0
如何快速定位并优化CPU 与 JVM 内存性能瓶颈?