【JVM】JAVA的运行时数据区

JVM : JAVA VIRTUAL MACHINE ,是一种虚构出来的机器。是虚拟的CPU,其中的很多组建都是模拟了CPU的功能。

运行时数据区及其主要功能

在这里插入图片描述
分布介绍一下不同区域的主要功能。

  • PC: Program Counter 程序计数器。存放指令的位置。在虚拟机运行中,CPU会从PC中获取将要执行的指令的地址,去该地址执行该指令,完成后,PC会继续下移到下一个指令的位置。

  • JVM Stack:线程栈,栈中存放栈帧,每个线程拥有自己的私有的线程栈空间,线程栈由栈帧构成,每个方法会形成一个栈帧。

      栈帧由如下几部分构成:
      
      1、局部变量表 : local variable table 类似于寄存器,存放方法中的参数和变量
    
      2、操作数栈: operand stack ,类似于内存。
      	所有数据必须都读取进操作数栈才能进行运算,是一个先进先出的栈结构。
      	主要用于保存计算的中间结果,同时作为计算过程中变量的临时存储空间。
      	
      3、动态链接: dynamic Linking。
      	动态链接是将一个符号引用解析为直接引用的过程。
      	A(){
      		c.B();
      	}
      	例如 : 当一个方法A中调用了 c类的B方法时 ,需要去常量池中c类
      	的class结构中找到B方法。当然首先要找到引用的c类,
      	如果有必要就要加载c类,将符号引用改为直接引用。
      	这样当再次遇到相同的引用时,可以直接使用这个直接引用,
      	不用再次解析。
    
      4、返回值地址: return address。
      	用于存放方法返回值的地址。当需要用到返回值时,就去该地址中获取返回值。
    
  • Heap : 堆 ,实例化对象的存储空间,线程共享。

    分代管理,GC回收的主要区域。

  • Method Area : 方法区。

    存放所有的class结构,所有线程共享

      a.	Perm Space (<1.8)  永久代
      	在小于1.8时,方法区也叫永久代
      	i.	字符串常量位于PermSpace FGC不会清理 大小启动的时候指定,不能变
      	
      b.	Meta Space (>=1.8) 元空间
      	在大于等于1.8时,方法区被称为元空间
      	i.	字符串常量位于堆 会触发FGC清理 不设定的话,最大就是物理内存
    
  • Run-time constant Pool : 运行时常量池,存在于方法区中。
    下面再详细介绍

  • Native method Area : 本地方法栈。
    是调用系统本地方法的栈空间。

常量池

说到常量池,就在这里顺便总结一下关于常量池的一些相关知识。

常量池分为三种,且均存在于方法区中。

全局字符串池:

全局字符串池里的内容是在类加载完成,经过验证,
准备阶段之后在堆中生成字符串对象实例,然后将该字符串对象实例
的引用值存到string pool中 (string pool中存的是引用值而
不是具体的实例对象,具体的实例对象是在堆中开辟的一块空间存放的)

在HotSpot VM里实现的string pool功能的是一个StringTable类,它是一个哈希表,里面存的是驻留字符串(也就是我们常说的用双引号括起来的)的引用(而不是驻留字符串实例本身),也就是说在堆中的某些字符串实例被这个StringTable引用之后就等同被赋予了”驻留字符串”的身份。这个StringTable在每个HotSpot VM的实例只有一份,被所有的类共享。

class 文件常量池:

这个最好了解一下class文件的结构。
在.class文件中除了包含类的版本、字段、方法、接口等描述信息外,
还有一项信息就是常量池(constant pool table)用于存放编译器
生成的各种字面量(常量)(Literal)和符号引用。

主要包括三种常量:
	类和接口的全限定名
	字段的名称和描述符
	方法的名称和描述符

运行时常量池:

jvm在执行某个类的时候,必须经过加载、连接、初始化,
而连接又包括验证、准备、解析三个阶段。而当类加载到内存中后,
jvm就会将class常量池中的内容存放到运行时常量池中,由此可知,
运行时常量池也是每个类都有一个

递归调用的压栈和弹出

首先要了解一下有关栈帧的执行过程:

1、一个栈中可以有多个栈帧,栈帧随着方法的调用而创建,随着方法的结束而消亡。

2、该栈帧中存储该方法中的变量,原则上各个栈帧之间的数据是不能共享的,但是在
方法间调用时,jvm会将一方法的返回值赋值给调用它的栈帧中。

3、每一个方法调用,就是一个压栈的过程,每个方法的结束就是一个弹栈的过程。

4、压栈都将会将该栈帧置于栈顶,每个栈不会同时操作多个栈帧,只会操作栈顶,当
栈顶操作结束时,会将该栈帧弹出,同时会释放该栈帧内存,其下一个栈帧将变为栈顶。

5、栈内存归属于单个线程,每个线程都会有一个栈内存,其存储的变量只能在其所属
线程中可见,即栈内存可以理解成线程的私有内存。

不想画图了,从网上找了一张图,以后有时间再话吧。。。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值