首页 > 其他分享 >JVM(三)运行时数据区概述及线程

JVM(三)运行时数据区概述及线程

时间:2023-05-17 19:14:07浏览次数:41  
标签:程序 指令 概述 JVM 寄存器 线程 CPU

目录

运行时数据区概述及线程

简介

内存是硬盘和CPU的中间仓库和桥梁,承载着操作系统应用程序的实时运行。JVM的内存布局规定了Java在运行过程中内存申请、分配、管理的策略,保证了JVM的高效稳定运行。不同的JVM对内存的划分方式管理机制存在着部分差异。

如下图,主要流程是类加载子系统加载字节码文件到内存相应区域,然后执行引擎对字节码文件进行解释执行,将字节码翻译为机器指令,同时也能够调用本地方法接口和本地方法库来调用C语言的方法,并存储数据到本地方法栈里面。

image-20221215100410037

可以看到上面的五种内存区域分成了两种颜色,灰色是线程独有的,红色是多个线程共享的(也就是进程的,进而也就是虚拟机实例的资源)。所以红色部分会随着虚拟机的创建而创建,随着虚拟机的退出而销毁。灰色部分则是与线程一一对应,这些线程对应的数据区域会随着线程的开始和结束创建和销毁。

即每个线程独立包括:程序计数器、本地方法栈、虚拟机栈

线程间共享:堆、堆外内存(永久代或元空间:即方法区的实现、代码缓存)

image-20221215101135300
线程间共享的说明

一个JVM实例也就是一个JVM虚拟机对应着一个Runtime对象,而Runtime对象就相当于上面的一个运行时数据区,可以通过getRuntime()方法获取。

JVM中的线程说明
  • 线程是一个程序的运行单元,JVM允许一个应用有多个线程并行地执行

  • 在HotSpot JVM里面,每个Java线程都和操作系统的本地线程直接映射。

    当一个Java线程准备好执行后,一个操作系统的本地线程也同时被创建,Java线程终止后,本地线程也会被回收。

  • 操作系统负责所有线程的安排调度到任何一个可用的CPU上,一旦本地线程初始化成功,就会调用Java线程中的run方法

  • 线程分为守护线程和普通线程,如果只剩下守护线程则本地线程会终止虚拟机

HotSpot JVM后台线程主要有下面几类:

image-20221215144907419

1 程序寄存器 Program Counter Register

JVM的程序计数寄存器命名起源于CPU的寄存器,用于存储指令相关的现场信息,CPU只有把数据装载到寄存器才能运行。JVM程序寄存器是对物理寄存器的一种抽象模拟,也称为是程序钩子,作用就是判断执行完上一行代码下一行该执行哪一行。

image-20221215153307081

作用:PC寄存器用来存储指向下一条指令的地址,也即是即将要执行的指令的代码,然后由执行引擎读取下一条指令。

  • 程序寄存器是内存中的一块很小的区域,几乎可以忽略不计,也是运行速度最快的区域

  • 在JVM规范中,程序寄存器是线程私有的,所以每个线程都有自己的程序寄存器,程序寄存器的生命周期和线程的生命周期一致

  • 任何一个时间一个线程都只会有一个方法在运行,这个方法即当前方法,程序寄存器会存储本地方法对应的JVM指令地址,当然如果这个方法是native的,即C语言的代码,就会不存储地址而是undefined

  • 它是程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都需要这个指示器来完成

  • 字节码解释器的工作就是通过改变这个计数器的值来选取下一条需要执行的字节码指令

  • 它是唯一一个Java虚拟机规范中没有规定任何OOM情况的区域

GC:垃圾回收机制主要是针对于堆区和方法区

OOM:即内存溢出,栈区、方法区和堆区都会发生,程序寄存器则不会

写一段代码然后对class文件执行反编译:javap -verbose xxx.class

    public static void main(String[] args) {
        int i = 10;
        int j = 20;
        int k = i + j;

        String s = "abc";
        System.out.println(i);
        System.out.println(k);
    }
 public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=5, args_size=1
         0: bipush        10
         2: istore_1
         3: bipush        20
         5: istore_2
         6: iload_1
         7: iload_2
         8: iadd
         9: istore_3
        10: ldc           #2                  // String abc
        12: astore        4
        14: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
        17: iload_1
        18: invokevirtual #4                  // Method java/io/PrintStream.println:(I)V
        21: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
        24: iload_3
        25: invokevirtual #4                  // Method java/io/PrintStream.println:(I)V
        28: return

反编译结果前面的数字即是程序寄存器存储的指令地址(偏移地址)执行引擎会从PC寄存器会根据地址取出后面是具体的操作指令,然后操作引擎使用操作局部变量表操作栈结构实现存取相加等等的操作,并将这些操作翻译成机器指令,交给CPU做具体的运算。

image-20221215162531307
为什么使用PC寄存器记录字节码指令地址?(为什么使用PC寄存器记录当前线程的执行地址)

因为CPU需要不停切换各个线程,所以切换回线程的时候需要知道从哪里开始继续执行。JVM的字节码解释器就需要改变程序寄存器的值来明确下一条执行那一条字节码指令。

image-20221215163832736
为什么程序计数器被设计成线程私有的

由于CPU时间片轮换的限制,多线程并发执行过程中,任何一个确定时刻,一个处理器或多核处理器的一个内核,只会执行某个线程中的一条指令。这样必然会导致线程经常中断或恢复,所以每个线程在创建之后都会产生自己的程序寄存器和栈帧,准确记录各个线程正在执行的字节码指令地址,保证线程在终端恢复后的正常执行。

CPU时间片即CPU分配给程序运行的时间

标签:程序,指令,概述,JVM,寄存器,线程,CPU
From: https://www.cnblogs.com/tod4/p/17409784.html

相关文章

  • JVM(五)本地方法接口
    JVM(五)本地方法接口和本地方法栈1本地方法一个NativeMethod就是一个Java调用非Java代码的接口。在定义本地方法的时候,不提供实现体标识符native能够和除了abstract的java标识符连用publicclassNativeTest{ publicnativevoidmethod1()throwException; .........
  • JVM(四)虚拟机栈(三)虚拟机栈面试题
    JVM(四)虚拟机栈(三)虚拟机栈面试题1举例栈溢出的情况?当方法调用不停将栈帧压入虚拟机栈导致栈内空间不足而出现StackOverFlowError即是出现了栈溢出可以通过-Xss设置栈的大小,栈的大小可以是固定的也可以是动态变化的,如果固定且超出设定值则就会出现栈溢出;如果是动态变化的,栈空......
  • 传动带料箱输送线程序,有合流和分拣,个人认为精华部分是WCS和PLC的Socket接口和分拣控制
    传动带料箱输送线程序,有合流和分拣,个人认为精华部分是WCS和PLC的Socket接口和分拣控制程序。提供设备布局图和电气图纸以及博途V16程序。程序源自欧企,无加密,外企程序还是比较美观的,程序仅供学习参考,不讲解,能从中学到多少看自己努力。硬件配置:PLC:1516F-3PN/DP,1212C等HMI:TP1200C......
  • 传动带料箱输送线程序,带目的地跟踪,提供设备布局图和电气图纸以及博途程序。
    传动带料箱输送线程序,带目的地跟踪,提供设备布局图和电气图纸以及博途程序。程序语言较多使用了STL,程序仅供学习参考。硬件配置:PLC:1515-2PNHMI:TP700Confort主要设备有:英特诺直流辊筒电机,控制卡MultiControl;条码阅读器SickCLV620;和MiniLoad堆垛机通过Anybus模块通讯;称重模块品......
  • Linux多进程01-进程概述
    程序与进程程序是包含一系列信息的文件,这些信息描述了如何在运行时创建一个进程进程是正在运行的程序的实例。是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。它是操作系统动态执行的基本单元,在传统的操作系统中,进程既是基本的分配单元,也是基本的执行单元。......
  • SRE Google 运维解密读书笔记一:SRE 方法论概述
    SREGoogle运维解密,是SRE领域的启蒙之作,讲述了Google的SRE实践,SRE就是从Google流传出来的。本文是读书笔记,第一篇,概述SRE方法论。帮大家把书读薄,当然,也加入了一些我的个人理解,希望对你有帮助。为何需要SRE传统的sysadmin的方式,偏手工运维,机器越多所需运维工程......
  • Linux下创建线程报错‘pthread_create’未定义的引用
    报错如下:我查找了网页上的解决方案,发现多数是因为编译链接时没有加-lpthread可是我加了,一直都在用;最终找出问题所在:函数名写错了pthread_create()而不是pthread_creat()细心是一种美好品质,希望我能尽快拥有它。......
  • Linux电源管理-Linux regulator framework概述
    一、前言1.什么是regulator?regulator翻译为"调节器",分为voltageregulator(电压调节器)和current(电流调节器)。一般电源管理芯片(PowerManagementIC)中会包含一个甚至多个regulator。2.regulator有什么作用?通常的作用是给电子设备供电。大多数regulator可以启用(enable......
  • 老杜MyBatis框架从入门到精通(一)MyBatis概述
    mybatis做为目前国内最为流行的开源orm框架,我们平时在使用时会感受到其带来的诸多便利,但是很少去深入分析,mybatis源码代码量不多,功能丰富,是一个很好的学习样例,本系列文章就和大家一起来学习mybatis框架本系列笔记根据动力节点B站上老杜讲的mybatis教程整理~学习地址:https://www......
  • Java-Day-22( 线程一:相关概念 + 继承 Thread 类 + 实现 Runnable 接口 + JConsole 监控
    Java-Day-22线程相关概念程序:是为完成特定任务、用某种语言编写的一组指令的集合(就是平常所写代码)进程:运行中的程序,例如,打开一个软件就启动一个进程,操作系统就会给每个启动的软件分配一新的内存(活动进程占用的物理内存)空间进程是程序的一次执行过程,或是正在运......