Jvm虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。这些区域都有各自的用途,以及创建和销毁的时间,Jvm所管理的内存将会包含以下几个运行时数据区域,如下图所示。
1.程序计数器
程序计算器是一块较小的内存空间,它的作用可以看做是当前线程所执行的字节码的行号指示器。字节码解释器工作时就是通过改变这个计数器的值来选取下一条所需要执行的字节指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。
由于jvm的多线程是通过线程轮流切换并通过分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器只会执行一条线程中的指令。因此,为了线程切换后能恢复到正确的位置,每条线程都需要有一个独立的线程计数器,各线程间的计数器互不影响,独立存储,我们称这类内存区域为”线程私有“的内存。
如果线程正在执行的是一个java方法,这个计数器记录的是正在执行的JVM字节码指令的地址;如果正在执行的是一个Native方法,这个计数器值为空。
2.虚拟机栈
与程序计数器一样,虚拟机栈也是线程私有的,它的生命周期与线程相同。虚拟机栈描述的是Java方法执行的内存模型:每个方法被执行的时候都会同时创建一个栈帧用于存储局部变量表、操作栈、动态链接、方法出口等信息。每一个方法被调用直到执行完成的过程,就对应着一个栈帧在虚拟机中从入栈到出栈的过程。
局部变量表存放了编译期可知的各种基本数据类型(boolean、byte、char、short、int、float、long、double)、对象引用和returnAddress类型(指向了一条字节码指令的地址)。
3.本地方法栈
本地方法栈与虚拟机栈所发挥的作用是非常相似的,其区别在于虚拟机栈为虚拟机执行Java方法服务,而本地方方法栈是为虚拟机使用到的Native方法服务。
4.堆
对大多数应用来说,堆是虚拟机所管理的内存中最大的一块。堆是被所以线程共享的一块区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,几乎所以的对象实例都在这里分配内存。堆同时也是垃圾收集器管理的主要区域。
5.方法区
方法区与堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。对HotSpot虚拟机来说,”永久代“也被划分到这个区域。一般来说这个区域的内存回收目标是针对常量池的回收和对类型的卸载。
6.运行时常量池
运行时常量池是方法区的一部分。Class文件中除了有类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池,用于存放编译器生成的各种字面量和符号引用,这部分内容将在类加载后存放到方法区的运行时常量池中。
7.直接内存
直接内存并不是虚拟机运行时数据区的一部分,但这部分内存也被频繁的使用,而且也可能导致OutOfMemoryError异常出现。
在JDK1.4中新加入了NIO类,引入了一种基于通道与缓冲区的I/O方式,它可以使用Native函数直接分配堆外内存,然后通过一个存储在Java堆里面的DirectByteBuffer对象作为这块内存的引用进行操作。这样能在一些场景中显著提高性能,因为避免了在Java堆和Native堆中来回复制数据。
对象访问
在Java语言中,对象的访问时如何进行的?即使最普通的对象访问也会涉及到Java堆、Java栈、方法区这三个最重要内存区域,如下面这段代码:
Object obj = new Object();
假设这句代码出现在方法体重,那“Object obj”这部分的语义将会反映到Java栈的本地变量表中,作为一个reference类型出现。而“new Object()”这部分语义将会反映到Java堆中,形成一块存储了Object类型所有实例数据的结构化内存。在Java堆中还必须包含能查找到此对象类型数据(如对象类型,父类,实现的接口,方法等)的地址信息,这些类型数据则存储在方法区中。
相关推荐
JVM运行时内存分区 程序计数器 程序计数器的特点 Java虚拟机栈 栈帧 局部变量表 操作数栈 动态连接 方法出口 本地方法栈 堆 方法区 JavaVirtualMachineError StackOverflowError OutOfMemoryError JVM PS:JVM部分...
JVM 内存区域JVM 内存区域JVM 运行时内存划分程序计数器Java虚拟机栈本地方法栈方法区运行时常量池直接内存HotSpot 虚拟机对象揭秘对象的创建对象
VM相关的一些内容,比如...垃圾回收机制: java 语言的优势之一就是它的自动内存管理,主要回收运行时数据区域的堆内存里的数据 类加载机制: 虚拟机首先需要把编译完成的字节码文件通过类加载器来加载到运行时数据区域
详细介绍了JVM 内存管理相关知识 内存空间( VM运行时数据区域) ◦ 内存结构 ◦ 内存空间 内存分配 内存回收(GC) 内存分析工具
常量池静态常量池即*.class文件中的常量池,用于存放字面量和符号引用运行时常量池是jvm运行期间,存储常量的数据结构运行时常量池概念运行时常量池(Runti
小池塘A(堆内存):JVM运行时数据区域,它为类实例和数组分配的内存。堆可以是固定大小的也可以是可变大小的。其中 Heap = {Old + NEW = { Eden , from, to } }。 小池塘B(非堆内存):包括所有线程之间共享的一个...
由于JVM运行的实体是线程 而每个线程创建时JVM都会为其创建工作内存 工作内存是每个线程的私有数据区域 而JAVA内存模型规定所有变量都存储在主内存 主内存是共享内存区域 所有线程都可以访问 但线程对变量的...
第28讲 Java内存区域-直接内存和运行时常量池 00:15:53 第29讲 对象在内存中的布局-对象的创建 00:21:19 第30讲 探究对象的结构 00:13:47 第31讲 深入理解对象的访问定位 00:08:01 第32讲 垃圾回收-...
虚拟机的历史版本和JAVA内存分配,未来的虚拟机技术, 运行时数据区域,方法的出入栈,栈上分配
类加载 、 类文件结构 、 垃圾回收 、 执行 引擎 、 性能调优 、 监控 等等这些知识,但所有的功能都是围绕着 内存结构 展开的,因为我们编译后的代码信息在运行过程中都是存在于JVM自身的内存区域中的...
最新jvm面试题合集,涵盖JVM运行时数据区、垃圾回收算法、垃圾回收器、类加载机制、JIT即时编译等核心知识点及常见面试题,一书在手,天下我有。 JVM内存结构:JVM的内存结构主要包括堆内存、方法区、栈(包括Java...
JVM 的运行机制 多线程 JVM 的内存区域 JVM 会创建操作系统的接口创建一个原生线程。JVM 线程和操作系统线程是一一对应的
基于JVM内存模型的String分析,王培,程明,本文首先介绍了运行时的Java程序的内存管理模型中的方法区、堆和Java栈等几块内存区域,又介绍了存于堆中的常量池这块比较特殊的内�
永久区:存储的是java的运行环境或类信息,这个区域不存在垃圾回收,关闭jvm就会释放内存 一个启动类加载大量的jar包。tomcat部署太多应用。内存满了就oom jdk1.6之前:永久代,常量池是在方法区 jdk1.7去...
系统运行一个程序就是进程从创建到运行再到消亡的过程。 线程 :一个进程中包含多个线程,线程共享进程的堆和方法区的资源以及直接内存,同时线程私有资源的包括 程序计数器 、 虚拟机栈 和 本地方法栈 。
第28节Java内存区域-直接内存和运行时常量池00:15:53分钟 | 第29节对象在内存中的布局-对象的创建00:21:19分钟 | 第30节探究对象的结构00:13:47分钟 | 第31节深入理解对象的访问定位00:08:01分钟 | 第32节垃圾...
JVM = 类加载器(classloader) + 执行引擎(execution engine) + 运行时数据区域(runtime data area)。 下面我们从每个区域的用途,涉及的问题等方面来简单的说一说JVM的内存结构。 方法区 作用:用于存放已被加载的...
JVM内存结构Java 代码是要运行在虚拟机上的,而虚拟机在执行 Java 程序的过程中会把所管理的内存划分为若干个不同的数据区域,这些区域都有各自的用途。如果