「每日五分钟,玩转JVM」:线程独占区

前言

如果我们对计算机组成有所了解,那么我们一定会知道在计算机中有一块儿特殊的区域,称之为寄存器,寄存器包括了指令寄存器和程序计数器,这两样位于CPU中,作为程序运行的大脑来控制程序的运行和流转。

而在JVM中,作为一种虚拟机,JVM没有指令寄存器,它是基于栈 + 程序计数器的体系结构来完成方法的执行,之所以这么去设计一方面是为了指令集的紧凑,一方面是有些平台上的寄存器很少或者根本没有,而且以处理器架构的角度来说,设计一套通用的寄存器指令是很困难的,而且还有一方面的考量就是有助于运行时某些虚拟机实现的动态编译器和即时编译器的代码优化。

程序计数器

我们在使用IDE写代码的时候,旁边经常会有行数,方便我们去阅读我们自己的代码,去定位我们代码的位置,而程序计数器是给JVM执行字节码过程中看的行号指示器,只不过他其中存的并非是行号,而是执行中虚拟机字节码指令的地址,也正是因为计数器中存储的仅仅是一条执行中的指令地址,使用的内存是及其有限的,所以这个区域是唯一一个没有OOM的区域。字节码解释器通过改变程序计数器中的地址来寻找对应的指令来完成对程序的控制(这里具体我们会在分析指令集时去详细的深入了解,这里仅仅点到为止)

这里需要注意一点,如果是本地Native 方法,该计数器的值是Undefined,其实也很好理解,人家压根不属于JVM去管理,你凭什么去记录。。这里我们使用的可以说是Native方法提供出的一个接口,具体的实现是通过C来完成的。

上节课我们说到多线程的实现是基于时分复用来实现的,为了每个线程的运行的互不干扰和有序性,程序计数器必须保证在切换时能够回到正确的位置,所以它必须必然是线程独占区的一份子。

关键字:

  • 行号指示器
  • 执行中字节码指令地址
  • 没有OOM
  • Native方法不归他管
  • 线程独享

虚拟机栈

虚拟机栈是Java方法运行时的内存模型,包括了局部变量表,操作数栈,动态连接,方法返回地址以及一些附加信息,每个方法在被执行的时候会在虚拟机栈中创造一个栈帧

栈帧在执行的时候创建压入栈,在完全执行完成后就会进行弹栈,下面是一个小??去直观的看一下过程~

(小声BB一句,这里不会制作GIF图,凑合着看吧。。)

下面简单介绍一下栈帧中的内容,这一部分我们会在了解字节码执行引擎的时候会进行更为详细的讲解。

  • 局部变量表

    局部变量表(Local Variable Table)是一组变量值存储空间,用于方法参数和方法内部定义的局部变量,包含了编译器可知的基本数据类型(byte,short,int,long,double,float,char,boolean),对象引用(reference)以及returnAddress类型。

  • 操作数栈

    同样是一个LIFO(Last In First Out,后入先出)的栈结构,用于计算的临时存储区,前面提过JVM是没有寄存器的,而操作数栈的作用就是让JVM的指令是从中获取操作数。

  • 动态连接

    每个栈帧都包含一个运行时常量池中该栈帧所属方法的引用,持有这个引用就是为了支持方法在调用过程中的动态连接

本地方法栈

和虚拟机栈相似,本地方法栈面向的对象不是JVM字节码,而是本地的Native方法,比如String类中的intern方法,Native方法更像是本地方法的提供的一个接口,而本地方法栈正是管理这些接口的一个区域。

public native String intern();

异常

本地方法栈和虚拟机栈同为栈结构之中,他们会面对两种异常,当线程请求的栈深度大于虚拟机所允许的深度时,将抛出StackOverflowError,如果栈可以动态扩展,如果扩展时无法申请到足够的内存,会抛出OOM异常

公众号

原文地址:https://www.cnblogs.com/viyoung/p/11410419.html

时间: 2024-10-11 18:41:43

「每日五分钟,玩转JVM」:线程独占区的相关文章

「每日五分钟,玩转JVM」:线程共享区

前言 上一篇中,我们了解了JVM中的线程独占区,这节课我们就来了解一下JVM中的线程共享区,JVM中的线程共享区是跟随JVM启动时一起创建的,包括堆(Heap)和方法区()两部分,而线程独占区的程序计数器,虚拟机栈,本地方法栈的生命周期都是跟随线程的,随线程的创建而诞生,随线程的销毁而销毁. 堆(Heap) 堆内存作为JVM管理的内存中最大的一块,用于存放我们的对象实例,我们经常会把JVM的内存简单的分为堆内存和栈内存,这样说虽然有些片面,但是也有这么说的道理,这两块儿一个作为执行程序的,一个作

「每日五分钟,玩转JVM」:对象从哪来

面向对象 众所周知,Java是一门面向对象的高级编程语言,那么现在问题来了,对象从哪来呢?有些人会说通过new关键字来创建一个对象,说的很好,本篇我们就来解密在new一个对象的过程中,JVM都给我们做了什么工作. 走哪来,到哪去 一个对象的诞生必定有一个类,通常我们都是通过new关键字实例化一个类来获取该类的一个对象,类在加载的过程中会经历一系列的检查,解析,初始化等一系列的过程,我们会在后面详细的分步骤进行讲解,这里我们只关心对象. 下面对象就要被加载到我们的虚拟机内存的堆内存中,加载到堆内存

HDFS-异常大全-《每日五分钟搞定大数据》

点击看<每日五分钟搞定大数据>完整思维导图以及所有文章目录 问题1:Decomminssioning退役datanode(即删除节点) 1.配置exclude: <name>dfs.hosts.exclude</name> <value>/data/hadoop/excludes</value> 在/data/hadoop/excludes文件添加要退役的节点ip(可同时退役多个,一个一行) 2.配置完后刷新节点 # $HADOOP_HOME/b

一篇文章搞懂DataSet、DataFrame、RDD-《每日五分钟搞定大数据》

1. 三者共性: 1.RDD.DataFrame.Dataset全都是spark平台下的分布式弹性数据集,为处理超大型数据提供便利 2.三者都有惰性机制,执行trainform操作时不会立即执行,遇到Action才会执行 3.三者都会根据spark的内存情况自动缓存运算,这样即使数据量很大,也不用担心会内存溢出 4.三者都有partition的概念,如 var predata=data.repartition(24).mapPartitions{       PartLine => {     

zookeeper-非常重要的zab协议-《每日五分钟搞定大数据》

上篇文章paxos与一致性说到zab是在paxos的基础上做了重要的改造,解决了一系列的问题,这一篇我们就来说下这个zab. zab协议的全称是ZooKeeper Atomic Broadcast即zookeeper"原子""广播"协议.它规定了两种模式:崩溃恢复和消息广播 恢复模式 什么时候进入? 当整个服务框架在启动过程中 当Leader服务器出现网络中断崩溃退出与重启等异常情况 当有新的服务器加入到集群中且集群处于正常状态(广播模式),新服会与leader进行

「每天五分钟,玩转 JVM」:对象访问定位

前言 在「对象内存布局」一节中,我们了解到对象头中包含了一个叫做类型指针的东西,即对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例.但是,并不是所有的虚拟机都是这么去做的.不同的虚拟机关于这点有不同的实现,目前主流的方式可以分为句柄和直接指针 句柄 由图中我们可以看到,在我们的堆中被划分出了一块单独的部分,叫做句柄池,句柄池的作用就像一个中转站,我们要查询位于堆内存中的对象实例数据,需要通过一次间接的索引去获取,而另一部分是指向方法区中的对象类型的指针.而此时JVM栈中

zookeeper-1.操作与应用场景-《每日五分钟搞定大数据》

Zookeeper作为一个分布式协调系统提供了一项基本服务:分布式锁服务,分布式锁是分布式协调技术实现的核心内容.像配置管理.任务分发.组服务.分布式消息队列.分布式通知/协调等,这些应用实际上都是基于这项基础服务由用户自己摸索出来的. 1.Zookeeper在大数据系统中的常见应用 zookeeper作为分布式协调系统在大数据领域非常常用,它是一个很好的中心化管理工具.下面举几个常见的应用场景. 1.1.HDFS/YARN HA(分布式锁的应用):Master挂掉之后迅速切换到slave节点.

redis- info调优入门-《每日五分钟搞定大数据》

本文根据redis的info命令查看redis的内存使用情况以及state状态,来观察redis的运行情况以及需要作出的相应优化. info 1.memory used_memory:13409011624 #used_memory=实际缓存占用的内存+Redis自身运行所占用的内存(如元数据.lua).                        #这个值是由Redis使用内存分配器分配的内存,不包括内存碎片浪费的内存. used_memory_rss:13740019719 #从操作系统上

YARN-异常大全-《每日五分钟搞定大数据》

#问题描述:NodeManager1 cpu负载飙高,进程还在但是不再向ResourceManager发送心跳,不断重复下文2的动作.心跳停止一段时间后会重连上RM但是cpu仍然很高,再过一段时间心跳再停,一直循环. #节点管理器的日志解析1.localizing:容器开始从HDFS下载资源,HDFS文件的状态从INIT变成下载. 2018年8月25日16:15:38592信息org.apache.hadoop .yarn.server.nodemanager.containermanager.