JAVA基础篇--JVM--2运行时数据区

前言:
我们知道jdk是将类加载到jvm 中运行的,当jvm通过类加载器将类加载到jvm后,并不是一股脑的将信息直接丢到内存中,它会将类的信息进行拆分并且存储到jvm 划分的各个地方;

本文将从以下几个方面来讨论jvm 的运行时数据区:
1 Jvm 的逻辑图;
2 jvm中类及对象信息的存储;
3 jvm 中的对象引用;

官网:https://docs.oracle.com/javase/specs/jvms/se8/html/index.html

1 Jvm 的逻辑图:
逻辑图:
在这里插入图片描述

2 jvm中类及对象信息的存储:
2.1 类及方法信息存储到方法区中(jdk1.8及之后为元空间):
2.1.1 方法区是各个线程共享的内存区域,在虚拟机启动时创建 :
The Java Virtual Machine has a method area that is shared among all Java Virtual
Machine threads. The method area is created on virtual machine start-up.
2.1.2 虽然Java虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却又一个别名叫做Non-Heap(非堆),目的是与Java堆区分开来 ;
Although the method area is logically part of the heap,…
2.1.3 方法区被用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据:
It stores per-class structures such as the run-time constant pool, field and
method data, and the code for methods and constructors, including the special
methods (§2.9) used in class and instance initialization and interface
initialization.
2.1.4 当方法区无法满足内存分配需求时,将抛出OutOfMemoryError异常
If memory in the method area cannot be made available to satisfy an allocation
request, the Java Virtual Machine throws an OutOfMemoryError;

2.2 类的实例对象及数组在存储到堆中:
2.2.1 Java堆是Java虚拟机所管理内存中最大的一块,在虚拟机启动时创建,被所有线程共享;
2.2.2 Java对象实例以及数组都在堆上分配:
The Java Virtual Machine has a heap that is shared among all Java Virtual
Machine threads. The heap is the run-time data area from which memory for all
class instances and arrays is allocated.
The heap is created on virtual machine start-up

2.3 类中方法的执行交由虚拟机栈完成:
2.3.1 虚拟机栈是一个线程执行的区域,保存着一个线程中方法的调用状态。换句话说,一个Java线程的运行状态,由一个虚拟机栈来保存,所以虚拟机栈肯定是线程私有的,独有的,随着线程的创建而创建;
Each Java Virtual Machine thread has a private Java Virtual Machine stack,
created at the same time as the thread
2.3.2 每一个被线程执行的方法,为该栈中的栈帧,即每个方法对应一个栈帧:
栈帧:
官网:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.6
每个栈帧中包括局部变量表(Local Variables)、操作数栈(Operand Stack)、指向运行时常量池的引用(Areference to the run-time constant pool)、方法返回地址(Return Address)和附加信息;
图解:
在这里插入图片描述

  • 局部变量表:方法中定义的局部变量以及方法的参数存放在这张表中局部变量表中的变量不可直接使用,如需要使用的话,必须通过相关指令将其加载至操作数栈中作为操作数使用。
  • 操作数栈:以压栈和出栈的方式存储操作数;
  • 动态链接:每个栈帧都包含一个指向运行时常量池中该栈帧所属方法的引用,持有这个引用是为了支持方法调用过程中的动态连接(Dynamic Linking)。
  • 方法返回地址:当一个方法开始执行后,只有两种方式可以退出,一种是遇到方法返回的字节码指令;一种是遇见异常,并且这个异常没有在方法体内得到处理。

2.4 记录线程执行到的位置 由The pc Register(程序计数器)控制:
我们都知道一个JVM进程中有多个线程在执行,而线程中的内容是否能够拥有执行权,是根据
CPU调度来的。 假如线程A正在执行到某个地方,突然失去了CPU的执行权,切换到线程B了,然后当线程A再获 得CPU执行权的时候,怎么能继续执行呢?这就是需要在线程中维护一个变量,记录线程执行到的位置。
如果线程正在执行Java方法,则计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是Native方法,则这个计数器为空。

TheJavaVirtualMachinecansupportmanythreadsofexecutionatonce(JLS
§17).EachJavaVirtualMachinethreadhasitsownpc(programcounter)
register.Atanypoint,eachJavaVirtualMachinethreadisexecutingthecode
ofasinglemethod,namelythecurrentmethod(§2.6)forthatthread.Ifthat
methodisnotnative,thepcregistercontainstheaddressoftheJavaVirtual
Machineinstructioncurrentlybeingexecuted.Ifthemethodcurrentlybeing
executedbythethreadisnative,thevalueoftheJavaVirtualMachine’spc
registerisundefined.TheJavaVirtualMachine’spcregisteriswideenoughto
holdareturnAddressoranativepointeronthespecificplatform.

2.5 前线程执行Native 方法交由Native Method Stacks(本地方法栈)
如果当前线程执行的方法是Native类型的,这些方法就会在本地方法栈中执行。
那如果在Java方法执行的时候调用native的方法呢?
在这里插入图片描述
除了上面五块内存之外,其实我们的JVM还会使用到其他两块内存 :
直接内存(Direct Memory)
并不是虚拟机运行时数据区的一部分,也不是JVM规范中定义的内存区域,但是这部分内存也被频
繁地使用,而且也可能导致OutOfMemoryError 异常出现,所以我们放到这里一起讲解。在JDK
1.4 中新加入了NIO(New Input/Output)类,引入了一种基于通道(Channel)与缓冲区
(Buffffer)的I/O 方式,它可以使用Native 函数库直接分配堆外内存,然后通过一个存储在Java 堆 里面的DirectByteBuffffer 对象作为这块内存的引用进行操作。这样能在一些场景中显著提高性能,因为避免了在Java 堆和Native 堆中来回复制数据。
本机直接内存的分配不会受到Java 堆大小的限制,但是,既然是内存,则肯定还是会受到本机总
内存的大小及处理器寻址空间的限制。因此在分配JVM空间的时候应该考虑直接内存所带来的影
响,特别是应用到NIO的场景。
其他内存:
Code Cache:**JVM本身是个本地程序,还需要其他的内存去完成各种基本任务,比如,JIT
编译器在运行时对热点方法进行编译,就会将编译后的方法储存在Code Cache里面;GC等
功能。需要运行在本地线程之中,类似部分都需要占用内存空间。这些是实现JVM JIT等功能
的需要,但规范中并不涉及。

3 jvm 中的对象引用:
3.1 栈指向堆 :
如果在栈帧中有一个变量,类型为引用类型,比如Object obj=new Object(),这时候就是典型的栈中元素指向堆中的对象。
在这里插入图片描述
3.2 方法区指向堆:
方法区中会存放静态变量,常量等数据。如果是下面这种情况,就是典型的方法区中元素指向堆中的对象。
private static Object obj=new Object();

在这里插入图片描述
3.3 堆指向方法区:
方法区中会包含类的信息,堆中会有对象,要想知道对象是哪个类创建,就需要推中欧的对象指向方法区中的类对象;
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值