Java虚拟机内存区域

Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。这些区域都有各自的用途,以及创建和销毁的时间。根据Java虚拟机规范,包括以下几个运行时数据区。

一、程序计数器

内存空间:较小。

作      用:当前线程所执行的字节码的行号指示器。

特性分析:Java虚拟机的多线程的执行是由线程轮流切换并分配处理器执行时间来完成的。在确定的某个时刻,一个处理器只会执行一条线程中的指令。因此,为了线程切换后能恢复到正确的的执行位置,每条线程都需要一个独立的程序计数器,各个线程之间计数互不影响,独立存储。

是线程私有的内存区域。

记录值:如果线程执行的是Java方法,那么记录的是正在执行的虚拟机字节码指令地址;如果线程执行的是Native方法,那么这个值为空。

此内存区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError的区域。

二、Java虚拟机栈

是线程私有的,生命周期与线程相同。

作用:描述的是Java方法执行的内存模型:每个方法被执行的时候都会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法被调用直至执行完成的过程,就对应着一个栈帧在栈中的入栈和出栈过程。

虚拟机栈中的局部变量表存放了编译期可知的各种基本数据类型(boolean、byte、char、short、int、float、long、double),对象引用。

引用类型不等同于对象本身,根据不同的虚拟机实现,它可能是一个指向对象起始地址的引用指针,也可能指向一个代表对象的句柄。

64位长度的long和double类型的数据会占用两个局部变量表空间(Slot),其余的数据类型只占用一个。局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时,这个方法需要在帧中分配多大的局部变量空间是完全确定的,在方法运行期间不会改变局部变量表的大小。

在Java虚拟机规范中,对虚拟机栈规定了两种异常情况:

(1)、如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常。

(2)、如果虚拟机栈可以动态扩展,当扩展无法申请到足够的内存时会抛出OutOfMemoryError异常。

三、本地方法栈

作用:与虚拟机栈是相似的。

区别:虚拟机栈为虚拟机执行Java方法(字节码)服务,而本地方法栈为虚拟机执行Native方法服务。

也会抛出StackOverflowError异常和OutOfMemoryError异常。

四、Java堆

内存空间:Java虚拟机所管理的内存中最大的 一块。

Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。

唯一目的:存放对象实例,几乎所有对象实例都在这里分配内存。

Java堆是垃圾收集器管理的主要区域,很多时候也被称为GC堆。

内存回收角度:Java堆分为新生代和老年代,再细致一些有Eden空间、From Survivo空间、To Survivor空间。

内存分配角度:可划分出多个线程私有的分配缓冲区(TLAB)。

无论如何划分,都与存放内容无关,无论哪个区域,存储的都是对象实例,进一步划分只是为了更好的回收内存或者更快的分配内存。

Java堆可以处于物理上的不连续内存空间中,只要逻辑上连续即可。在实现上,既可以是固定的,也可以是可扩展的。

如果在堆中没有内存完成实力分配,并且堆也无法再扩展时,将会抛出OutOfMemoryError异常。

五、方法区

方法区和Java堆一样,也是各个线程共享的区域,也可以处于不连续的物理内存空间,也可选择固定或者可扩展。

作用:用于存储被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

在方法区很少进行垃圾收集行为,在这个区域的内存回收目标主要是针对常量池的回收和类型的卸载。

当无法满足内存分配需求时,将会出现OutOfMemoryError异常。

六、运行时常量池

运行时常量池是方法区的一部分。

Class文件中的常量池信息(用于存放编译期生成的各种字面量和符号引用)在类加载后存放到运行时常量池中。

Java虚拟机对Class文件的每一个部分的格式都有严格的规定,每一个字节用于存储哪种数据都必须符合规范上的要求,这样才能被虚拟机认可、装在和执行。但是对运行时常量池,Java虚拟机规范没有做任何细节的要求。不同的供应商实现的虚拟机可以按照自己的需要来实现这个内存区域。

运行时常量池相对于Class文件中的常量池的另外一个重要特征就是具备动态性,Java语言要求常量不一定只能在编译期间产生,运行期间也可以将新的常量放入运行时常量池。比如String类的intern()方法。

七、直接内存

直接内存并不是虚拟机运行时数据区的一部分,也不是Java虚拟机规范中定义的内容区域。但是也会出现OutOfMemoryError异常。

时间: 2024-11-05 20:37:53

Java虚拟机内存区域的相关文章

Java虚拟机内存区域详解

众所周知,Java程序运行于Java虚拟机(JVM)上,那么,JVM运行的时候内存是如何分配的呢?程序中各部分变量都存储在内存的哪个部分,又如何访问,下面,就让我来给大家讲解Java虚拟机内存区域. 为什么需要了解Java虚拟机内存区域 相对于C++程序员,因为虚拟机的自动内存管理机制的存在,Java程序员很多时候并不需要去担心内存的泄露和内存溢出的问题.但是正是因为把内存的控制权交给了JVM,一旦出现内存泄露和溢出的问题,如果不了解虚拟机怎么使用内存,就很难排查错误. 内存泄露:一些对象在使用

java虚拟机内存区域理解

java虚拟机有的区域随着虚拟机进程的启动而存在, 有的区域依赖用户线程的启动和结束而建立和销毁. 程序计数器:为了线程切换后能恢复到正确的执行位置,每个线程都有一个独立的程序计数器.(针对java方法,即栈) 虚拟机栈:为了虚拟机执行java方法,线程创建时就会创建一个栈帧,存储局部变量表.操作数栈.动态链接等. StackOverFlowError:线程请求的栈深度大于虚拟机所允许的深度: OutOfMemoryError:动态扩展是无法申请到足够的内存. 本地方法栈:为了虚拟机使用到Nat

java虚拟机内存区域的划分以及作用详解

序言 为什么有时候学着学着会突然之间觉得一切度是那么无趣,男的每个月也有那么几天难道?哈哈,不然是什么,我还是要坚持,可以做少一点,但是不能什么度不做.总会过去的,加油 --WH 一.运行时数据区 什么叫运行时数据区呢,看下图就知道了,今天的重点就围绕这张图讲. 1.程序计数器(寄存器) 当前线程所执行的字节码行号指示器 字节码解释器工作依赖计数器控制完成 通过执行线程行号记录,让线程轮流切换各条线程之间计数器互不影响 线程私有,生命周期与线程相同,随JVM启动而生,JVM关闭而死 线程执行Ja

Java虚拟机内存区域堆(heap)的管理

在上一节中Java 出现内存溢出的定位以及解决方案 中对于Java虚拟机栈以及方法区的内存出现的异常以及处理方式进行了解析,由于Java虚拟机对于堆的管理十分复杂,并且Java虚拟机中最基本的内存区域,所以单独提出一节进行分析. 先来解释一下对象存活?? 什么样的对象是已经死了的对象,须要垃圾回收器进行回收.这个概念至关重要.由于它影响到垃圾回收器对于哪一个对象进行回收.能够从GCRoot訪问到的对象是存活的对象,那么以外的对象就是已死的对象. GCRoot:包含四种 1)Java虚拟机栈中存放

《深入理解Java虚拟机》笔记 第二章 Java虚拟机内存区域

? ? 这句话感觉道出了GC的本质 ? ? ? ? ? ? 1.程序计数器(Program Counter Register) ? ? 程序计数器是一块较小的内存空间,它的作用可以看做是当前线程所执行的字节码的行号指示器.字节码解释器工作时就是通过改为这个计数器的值来选取下一条需要执行的字节码指令,分支.循环.跳转.异常处理.线程恢复等基础功能都需要依赖这个计数器来完成. ? ? 由于Java虚拟机的多线程是通过线程轮流切换CPU时间片的方式来实现的,所以在任何一个时刻,一个处理器(对于多核处理

Java 虚拟机内存区域划分详解(1)

一.概述 对于 C 和 C++程序开发的开发人员来说,在内存管理领域,程序员对内存拥有绝对的使用权,但是也要主要到正确的使用和清理内存,这就要求程序员有较高的水平. 而对于 Java 程序员来说,在虚拟机的自动内存管理机制的帮助下,不再需要为每一个 new 操作去写配对的 delete/free 代码,而且不容易出现内存泄漏和内存溢出问题,看起来由虚拟机管理内存一切都很美好.不过,也正是因为 Java 程序员把内存控制的权力交给了 Java 虚拟机,一旦出现内存泄漏和溢出方面的问题,如果不了解虚

java虚拟机内存划分

java虚拟机内存区域 参照官方文档 1.8版本 Oracle虚拟机内存划分文档 : https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.5 The Java Virtual Machine defines various run-time data areas that are used during execution of a program. Some of these data areas are

从一道面试题深入了解java虚拟机内存结构

记得刚大学毕业时,为了应付面试,疯狂的在网上刷JAVA的面试题,很多都靠死记硬背.其中有道面试题,给我的印象非常之深刻,有个大厂的面试官,顺着这道题目,一直往下问,问到java虚拟机的知识,最后把我给问住了. 我当时的表情是这样的: 后来我有机会面试别人了,也按照他的思路出面试题,很多已经工作了2年的程序员,结果也和我当年一样,都败在java虚拟机知识上. 我们先看面试题: String str1 = "hello Alunbar"; String str2 = new String(

java虚拟机---内存

java虚拟机---内存 Java虚拟机,即JVM,负责运行java程序,每个java程序都运行在一个具体jvm实例上.Java虚拟机的体系架构分为:类装载子系统.运行时数据区.执行引擎.类装载子系统即负责加载.验证.解析.初始化java类的系统:Java虚拟机在运行一个程序时需要储存很多数据,如类装载信息.创建的实例对象.方法调用的参数.局部变量.中间值等,虚拟机把这些信息都储存在"运行时数据区"里,即这里讲的JVM内存:执行引擎则是以字节码形式的class文件为输入,运行程序输出计