根据《Java虚拟机规范(第二版)》的规定,Java虚拟机所管理的内存将会包括以下几个运行时数据区域
程序计数器 作用可以看做是当先线程所执行的字节码的信号指示器。
每一条JVM线程都有自己的程序计数器(“线程私有”内存);
在任意时刻,一条JVM线程只会执行一个方法的代码。该方法称为该线程的当前方法(Current Method);
如果该方法是java方法,那程序计数器保存JVM正在执行的字节码指令的地址;
如果该方法是native,那程序计数器的值是undefined;
此内存区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域。
虚拟机栈 描述的是Java方法执行的内存模型:每个方法被执行的时候都会同时创建一个栈帧(Stack Frame)用于存储局部变量、操作栈、动态链接、方法出口等信息。
与程序计数器一样,虚拟机栈也是线程私有,生命周期与线程相同;
存放编译器可知的各种基本数据类型(boolean、byte、char、shot、int、long、float、double)、对象引用(reference类型,非对象本身)、和returnAddress类型(指向了一条字节码指令的地址);
64位类型数据会占用2个局部变量空间,其他数据类型只占用1个;
局部变量表所需的空间在编译器间即完成分配,在方法运行期间不会改变局部变量表的大小;
在此区域规定了两种异常情况:如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常;如果虚拟机栈可以动态扩展,当扩展时无法申请到足够的内存时会抛出OutOfMemoryError。
本地方法栈 与虚拟机栈作用类似,区别是为虚拟机使用到的Native方法服务。
在此处,虚拟机规范没有做强制规定,各厂商可以自由实现。甚至Sun HotSpot虚拟机将本地方法栈与虚拟机栈合二为一。
此位置也会抛出StackOverflowError和OutOfMemoryError。
Java堆 是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存(规范规定:The heap is the runtime data area from which memory for all class instances and arrays is allocated.)。
Java堆是GC管理的主要区域。从内存回收的角度来看,Java堆可以细分为:新生代和老年代;再细致一些可以分为Eden空间、From Survivor空间、To Survivor空间等;如果从内存分配角度看,线程共享的Java堆中可能划分出多个线程私有的分配缓冲区(Thread Local Allocation Buffer, TLAB);
可以处于物理上不连续的内存空间中,只要逻辑上是连续的即可;
如果在堆中没有足够的内存来完成实例分配,并且堆也无法再扩展时,将会抛出OutOfMemoryError。
方法区 用于存储已被虚拟机加载的类信息,常量、静态变量、即时编译器编译后的代码等数据。
被各个线程共享的内存区域;
对此区域的垃圾回收目标主要在于常量池的回收和对类型的卸载。一般来说对这个区域的内存回收成绩比较难以令人满意,因为类型卸载的条件相当严苛。
运行时常量池 存放编译器生成的各种字面常量和符号引用。
此区为方法区的一部分;
运行时常量池相比于Class文件常量池的另外一个重要特性是具备动态性,常量并不一定只能在编译期产生,运行期间也可能将新的常量放入池中,例:String的intern()方法
直接内存 使用Native函数库直接分配堆外内存。
并不是虚拟机运行时数据区的一部分,也不是Java虚拟机规范中定义的内存区域;
因为直接在内存中分配,不会受到Java堆大小的限制,但会受到本机实际内存大小的限制。而且这部分的配置容易被遗忘,在管理员设置 -Xmx等参数时忽略此区域,使得各个内存区域总和比物理内存大小更大。
相关推荐
VM相关的一些内容,比如...垃圾回收机制: java 语言的优势之一就是它的自动内存管理,主要回收运行时数据区域的堆内存里的数据 类加载机制: 虚拟机首先需要把编译完成的字节码文件通过类加载器来加载到运行时数据区域
JVM内存结构Java 代码是要运行在虚拟机上的,而虚拟机在执行 Java 程序的过程中会把所管理的内存划分为若干个不同的数据区域,这些区域都有各自的用途。如果
主要关于java虚拟机的运行时数据区域,参考了周志明的深入理解java虚拟机,还涉及到了native方法、垃圾回收机制等等。
主要介绍了详解Java虚拟机管理的内存运行时数据区域的相关资料,需要的朋友可以参考下
Java虚拟机所管理的内存将会包括以下几个运行时数据区域,如下图所示: 下面每一个区域进行阐述。 二、运行时数据区域 程序计数器 程序计数器,可以看做是当前线程所执行的字节码的行号指示器。在...
java虚拟机运行数据区如图所示。 1、程序计数器 是一块较小的内存空间,是当前线程所执行的字节码的行号指示器。如果线程正在执行一个java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;...
工作内存是每个线程的私有数据区域 而JAVA内存模型规定所有变量都存储在主内存 主内存是共享内存区域 所有线程都可以访问 但线程对变量的操作必须在工作内存中进行 首先要将变量从主内存拷贝到自己的工作内存...
Java虚拟机在执行Java程序的过程中会把他所管理的内存划分为若干个不同的数据区域。Java虚拟机规范将JVM所管理的内存分为以下几个运行时数据区:程序计数器、Java虚拟机栈、本地方法栈、Java堆、方法区。下面详细...
常量池静态常量池即*.class文件中的常量池,用于存放字面量和符号引用运行时常量池是jvm运行期间,存储常量的数据结构运行时常量池概念运行时常量池(Runti
Java虚拟机在执行Java程序的过程中会把他所管理的内存划分为若干个不同的数据区域。Java虚拟机规范将JVM所管理的内存分为以下几个运行时数据区:程序计数器,Java虚拟机栈,本地方法栈,Java堆,方法区。下面详细...
由于JVM运行程序的实体是线程,而每个线程创建时JVM都会为其创建一个工作内存(有些地方称为栈空间),工作内存是每个线程的私有数据区域,而Java内存模型中规定
与我一起学 JVM:Java 虚拟机内存组成概念前言Java 虚拟机内存划分运行时数据区域程序计数器Java 虚拟机栈局部变量表本地方法栈Java 堆方法区运行时常量池直接内存 前言 刚开始看《深入理解Java虚拟机》,文章主要就...
首先我们要了解我们为什么要学习java虚拟机的内存管理,不是java的gc垃圾回收机制都帮我们...Java虚拟机所管理的内存将会包括以下几个运行时数据区域,如下图所示:我认为我们最重要的是了解栈内存(Stack)和堆内存
详细介绍了JVM 内存管理相关知识 内存空间( VM运行时数据区域) ◦ 内存结构 ◦ 内存空间 内存分配 内存回收(GC) 内存分析工具
在说Java内存模型之前,我们先说一下Java的内存结构,也就是运行时的数据区域:Java虚拟机在执行Java程序的过程中,会把它管理的内存划分为几个不同的数据区域,这些区域都有各自的用途、创建时间、销毁时间
JVM内存区域2.2.1. 程序计数器(线程私有).2.2.2. 虚拟机栈(线程私有)..2.2.3. 本地方法区(线程私有)..2.2.4. 堆(Heap-线程共享)-运行时数据区,2.2.5. 方法区/永久代(线程共享)2.3. JVM 运行时内存2.3.1. 新生代.2.3...