当Java虚拟机运行时,它需要内存来存取很多东西。例如,字节码,从已经装载的class文件中得到的其他信息,程序创建的对象,传递给方法的参数,返回值,局部变量,已经运算的中间结果等。Java虚拟机把这些数据都组织到几个“运行时数据区”,以便于管理,主要包括方法区、堆、Java栈、PC寄存器、本地方法栈。
方法区
在Java虚拟机中,关于被装载的类型的信息存储在一个逻辑上被称为方法区的内存中。当虚拟机装载某个类型时,它使用类装载器定位相应的class文件,然后读入这个class文件--------一个线性二进制数据流--------然后把它传输到虚拟机中。紧接着虚拟机提取其中的类型信息,并将这些信息存储到方法区。该类型中的类(静态)变量同样也存储在方法区中。
由于所有线程都共享方法区,因此它们对方法区数据的访问必须被设计是线程安全的。比如,假设同时两个线程都企图访问一个名为Lava的类,而这个类还没有内装载入虚拟机,那么,这时应该只有一个线程去装载它,而另一个线程则只能等待。
对每个装载的类型,虚拟机都会在方法区中存储一下类型信息:
l 这个类型的全限定名
l 这个类型的直接超类的全限定名(除了Object)
l 这个类型的是类类型还是接口类型
l 这个类型的访问修饰符
l 任何直接超接口的全限定名的有序列表
除了上面的基本信息以外,虚拟机还得为每个被装载的类型存储以下信息:
l 该类型的常量池
l 字段信息
l 方法信息
l 除了常量以外的所有类变量
l 一个到ClassLoader的引用
l 一个到Class类的引用
指向ClassLoader的引用
每个类型被装载的时候,虚拟机必须跟踪它是由启动类装载器还是由用户自定义类装载器装载的。如果是用户自定义类装载器装载的,那么虚拟机必须在类型信息中存储对该类型装载器的引用。这是作为方法表中的类型数据的一部分保存的。
虚拟机会在动态连接期间使用这个信息。当某个类型引用另一个类型的时候,虚拟机会请求装载发起引用的类装载器来装载被引用的类型。这个动态连接的过程,对于虚拟机分离命名空间的方式也是至关重要的。为了能够正确执行动态连接以及维护多个命名空间,虚拟机需要在方法表中得知每个类都是哪个类装载器装载的。
指向Class的引用
对于每个被装载的类型(不管是类还是接口),虚拟机都会相应地为它在堆上创建一个java.lang.Class类的实例,而且虚拟机还必须以某种方式把这个实例和存储在方法区中的类型数据关联起来。
在程序中,可以使用指向Class对象的引用。Class类中的两个方法可以得到任何已装载的类的Class实例的引用。分别是Class.forName(“”)以及Class.getClass()。
给出一个Class对象的引用,就可以通过Class类中的定义的方法来找出这个类型的相关信息。如果查看这些方法会很快意思到,Class类使得运行程序可以访问方法区中保存的信息。下面的是Class类中声明的方法:
public string getName(); 返回类的全限定名
public Class getSuperClass(); 返回类型的直接超类实例(object或者接口返回null)
public boolean isInterface(); 判断该类型是否是接口
public Class[] getInterfaces(); 返回一个Class对象数组,每个Class对象对应一个直接超类接口,如果该类型没有直接超接口,getInterfaces()返回一个0长度数组
public ClassLoader getClassLoader(); 返回该类型的ClassLoader对象的引用
堆
Java程序在运行时创建的所有类实或数组都放在同一个堆中。而一个Java虚拟实例中只存在一个堆空间,因此所有线程都将共享这个堆。
Java对象中包含的基本数据由他所属的类及其所有超类声明的实例变量组成。只要有一个对象引用,虚拟机就必须能够快速的定位对象实例的数据。另外,它也必须能通过该对象引用访问相应的类数据(存储于方法区的类型信息)。因此在对象中通常会有一个指向方法区的指针。
程序计数器
每个运行中的Java程序,每一个线程都有它自己的PC寄存器,也是该线程启动时创建的。PC寄存器的内容总是指向下一条将被执行指令的饿“地址”,这里的“地址”可以是一个本地指针,也可以是在方法区中相对应于该方法起始指令的偏移量。
Java栈
Java栈以帧为单位保存线程的运行状态。虚拟机只会直接对Java栈执行两种操作:以帧为单位的压栈或出栈。
和方法区和堆一样,Java栈和帧在内存中也不必是连续的。帧可以分布在连续的栈里,也可以分布在堆里,或者两者兼有的。
栈帧
栈帧由三部分组成:局部变量、操作数栈和帧数据区。
当虚拟机调用一个Java方法时,它从对应类的而类型信息中得到此方法的局部变量区和操作数栈的大小,并据此分配栈帧内存,然后压入Java栈中。
局部变量:存放局部变量和方法参数
操作数栈:线程的工作区,用来存放运算过程中的临时数据
帧数据区:保存支持常量解析、正常方法返回以及异常派发机制的数据
分享到:
相关推荐
03 JVM 运行时数据区概述及线程的 PPT 重绘。讲述 Java 虚拟机 运行时数据区所处位置,结构划分,以及各个区域与线程的关系。
深入理解Java运行时数据区_动力节点Java学院整理,动力节点口口相传的Java黄埔军校
Java8 Jdk JVM学习笔记、jdk1.8、...主要内容为 JVM 内存与垃圾回收、类加载子系统、运行时数据区、本地方法等。适合开发1-3年想对JVM学习的同学。 在之后的开发中,更加详细的了解JVM,可以进行JVM问题排查。
Java运行时数据区划分原理解析 Java运行时数据区划分原理是Java虚拟机中的一种内存管理机制,它将内存区域划分为不同的部分,每个部分都有其特定的作用和功能。了解Java运行时数据区划分原理对于Java程序员来说非常...
JVM运行时数据区原理解析 JVM运行时数据区是Java虚拟机中最重要的组成部分之一,它是JVM运行时的核心区域,负责存储和管理程序运行时需要的数据。根据JVM规范,JVM运行时数据区可以分为五个部分:PC寄存器、虚拟机...
"JVM运行时数据区划分原理详解" JVM运行时数据区划分原理详解是Java虚拟机(JVM)的核心组件之一,负责管理Java应用程序的内存资源。该原理详解了JVM如何划分和管理内存空间,以便更好地支持Java应用程序的运行。 ...
4. 运行时数据区 关于运行时数据官方解释:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.5 4.1 堆 (heap) 堆在虚拟机中是一块共享区域, 存放 对象实例 和数组; 堆在虚拟机启动的时候...
文章强调,随着电力企业生产运行数据的积累,电力大数据挖掘技术为电力系统的设备运行参数状态评估提供了有效的手段。电力大数据聚类分析技术可以理解为一种从海量数据中抽取有价值模式和规律的复杂过程。在电力系统...
水处理设备运行数据记录表 水处理设备运行数据记录表是记录水处理设备运行情况的重要文档。它是水处理厂、水厂、污水处理厂等单位记录水处理设备运行情况的必备文件。下面我们将详细介绍水处理设备运行数据记录表的...
Java虚拟机(JVM)是Java Virtual Machine的缩写,...类加载器负责将字节码文件加载到内存中,运行时数据区用于存储程序执行时所需的数据,执行引擎则负责执行字节码文件,而垃圾收集器则负责回收不再使用的内存空间。
4. 在使用DSO算法处理KITTI数据集时,由于KITTI数据集不包含曝光参数和矫正信息,因此不需要在运行DSO算法时添加gamma和vegene参数。 5. KITTI数据集提供的校准参数文件(calib文件)与DSO算法的要求不完全相同。...
数据中心运行管理技术,作为企业数据中心建设参考
1.0.1为实现数据中心基础设施系统与设备运行维护的规范性、 安全性和及时性确保电子信息设备运行环境的稳定可靠,制订本 标准 1.0.2本标准适用于已投入运行的数据中心 1.0.3数据中心基础设施的运行维护除应符合本...
调度数据网运行规程1.pdf调度数据网运行规程1.pdf调度数据网运行规程1.pdf调度数据网运行规程1.pdf调度数据网运行规程1.pdf
7. 运行时初始化:涉及各种运行时函数的分类,包括参数访问、缓冲区操作、字符分类、数据转换等。 8. 调试例程:为程序开发提供调试功能,帮助开发者发现和定位问题。 9. 文件处理:包括文件输入输出操作,浮点...
大数据技术的应用能够处理大量电力设备的运行数据,建立共享平台,对这些数据进行深入分析和管理。大数据技术包括但不限于Hadoop云计算框架、HDFS存储技术、MapReduce并行计算技术、HBase数据库、Sqoop数据导入导出...
水处理设备运行数据记录表 水处理设备运行数据记录表是记录水处理设备运营情况的重要文件,以下是从该表格中提取的相关知识点: 1. 水处理设备的类型:根据表格中的内容,可以推断出水处理设备包括石英砂过滤器、...