java内存结构(执行时数据区域)

java虚拟机规范规定的java虚拟机内存事实上就是java虚拟机执行时数据区,其架构例如以下:

当中方法区和堆是由全部线程共享的数据区。

Java虚拟机栈。本地方法栈和程序计数器是线程隔离的数据区。

(1).程序计数器:

是一块较小的内存空间,其作用能够看作是当前线程所运行的字节码的行号指示器,字节码解析器工作时通过改变程序计数器的值来选取下一条须要运行的字节码指令。

程序的分支、循环、跳转、异常处理以及线程恢复等基础功能都是依赖程序计数器来完毕。

Java虚拟机的多线程是通过线程轮流切换并分配处理器运行时间片来实现。在不论什么一个时刻,一个处理器仅仅会运行一条线程指令。因此。为了确保线程切换之后能恢复到正确的运行位置,每条线程都须要一个独立的程序计数器,因此程序计数器是线程私有的内存。

程序计数器是java虚拟机中唯一一个没有规定不论什么内存溢出OutOfMemoryError的内存区域。

(2).java虚拟机栈:

Java虚拟机栈也是线程私有的。它的生命周期与线程同样。

虚拟机栈描写叙述的是java方法运行的内存模型:每一个方法被运行时都会同一时候创建一个栈帧用于存放局部变量表、操作数栈、动态连接和方法出口等信息。每一个方法被调用直至运行完毕过程,就相应着一个栈帧在虚拟机中从入栈到出栈的过程。

Java虚拟机栈的局部变量表存放了编译器可知的8种java基本类型数据、对象引用(注意不是对象实例本身)、方法返回地址returnAddress。

Java虚拟机栈的局部变量表空间单位是槽(Slot),当中64位长度的double和long类型会占用两个slot。其余的数据类型仅仅占用一个slot。

局部变量表所需内存空间在编译期间完毕分配,当进入一个方法时。该方法须要在帧中分配多大的局部变量空间是全然确定的,在方法执行期间不会改变局部变量表的大小。

Java虚拟机栈有两种异常状况:假设线程请求的栈深度大于虚拟机所同意的最大深度时,抛出StackOverflowError异常;假设虚拟机栈能够动态扩展,当扩展时无法申请到足够内存时会抛出OutOfMemoryError异常。

(3).本地方法栈:

本地方法栈与java虚拟机栈作用很类似。其差别是:java虚拟机栈是为虚拟机运行java方法服务。而本地方法栈是为虚拟机调用的操作系统本地方法服务。

Java虚拟机规范没有对本地方法栈的实现和数据结构做强制规定。Sun HotSpot虚拟机直接把java虚拟机栈和本地方法栈合二为一。

与java虚拟机栈类似,本地方法栈也会抛出StackOverflowError异常和OutOfMemoryError异常。

(4).堆:

堆是java虚拟机所管理的内存区域中最大一块,java堆是被全部线程所共享的一块内存区域。在java虚拟机启动时创建。堆内存的唯一目的就是存放对象实例。差点儿全部的对象实例都是在堆分配内存。

Java堆是垃圾收集器管理的主要区域。从垃圾回收的角度看,因为如今的垃圾收集器基本都採用的是分代收集算法。因此java堆还能够初步细分为新生代和年老代。

Java虚拟机规范规定,堆能够处于物理上不连续的内存空间中,仅仅要逻辑上是连续的就可以。在实现上即能够是固定大小的。也能够是可动态扩展的。假设在堆中没有内存完毕实例分配,而且堆大小也无法在扩展时,将会抛出OutOfMemoryError异常。

(5).方法区:

方法区与堆一样,是被各个线程共享的内存区域。它用于存储已被虚拟机载入的类信息、常量、静态变量、即时编译后的代码等数据。尽管java虚拟机规范把方法区描写叙述为堆的一个逻辑部分,可是方法区却有一个别名叫Non-Heap(非堆)。

Sun HotSpot虚拟机把方法区叫永久代(Permanent Generation),方法区中最重要的部分是执行时常量池。

Class文件里除了有类的版本号、字段、方法、接口等描写叙述信息外,另一项信息是常量池。用于存放编译期生成的各种字面变量、符号引用、直接引用等,这些内容将在类载入后存放到方法区的执行时常量池中,另外在执行期间也能够将新的常量存放到常量池中,如String的intern()方法。

方法区和执行时常量池在无法满足内存分配时,也会抛出OutOfMemoryError异常。

(6).直接内存:

直接内存并非java虚拟机执行时数据区的一部分,也不是java虚拟机规范中定义的内存区域。可是在java开发中还是会使用到。

JDK1.4中新引入的NIO(new I/O),引入了一种基于通道(Channel)和缓冲区(Buffer)的I/O方式,能够使用操作系统本地方法库直接分配堆外内存,然后通过一个存储在java堆里面的DirectByteBuffer对象作为堆外直接内存的引用进行操作,避免了java堆内存和本地直接内存间的数据拷贝,能够显著提高性能。

尽管直接内存并不直接收到java虚拟机内存影响。可是假设java虚拟机各个内存区域总和大于物理内存限制,从而导致直接内存不足,动态扩展时也会抛出OutOfMemoryError异常。

java虚拟机内存结构中的程序计数器、虚拟机栈和本地方法栈这三个区域随线程创建而生,随线程销毁而灭,因此这三个区域的内存分配和回收是确定的。java垃圾收集器重点关注的是java虚拟机的堆内存和方法区内存。

时间: 2024-10-03 13:58:11

java内存结构(执行时数据区域)的相关文章

java内存结构(运行时数据区域)

java虚拟机规范规定的java虚拟机内存其实就是java虚拟机运行时数据区,其架构如下: 其中方法区和堆是由所有线程共享的数据区. Java虚拟机栈,本地方法栈和程序计数器是线程隔离的数据区. (1).程序计数器: 是一块较小的内存空间,其作用可以看作是当前线程所执行的字节码的行号指示器,字节码解析器工作时通过改变程序计数器的值来选取下一条需要执行的字节码指令.程序的分支.循环.跳转.异常处理以及线程恢复等基础功能都是依赖程序计数器来完成. Java虚拟机的多线程是通过线程轮流切换并分配处理器

JVM内存结构——运行时数据区

在Java虚拟机规范中将Java运行时数据划分为6种,分别为: PC寄存器(程序计数器) Java栈 堆 方法区 运行时常量池 本地方法栈 一.PC寄存器(程序计数器) PC寄存器(Program Counter Register)严格来说是一个数据结构,它用于保存当前正常执行的程序的内存地址. 线程私有. 每个线程启动的时候,都会创建一个PC(Program Counter,程序计数器)寄存器.PC寄存器里保存有当前正在执行的JVM指令的地址. 每个线程都需要一个独立的程序计数器,各条线程之间

深入理解Java虚拟机:运行时数据区域

Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有些区域则依赖用户线程的启动和结束而建立和销毁.根据<Java虚拟机规范(Java SE 7版)>的规定,Java虚拟机所管理的内存将会包括以下几个运行时数据区域. 程序计数器 程序计数器(Program Counter Register)是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器.在虚拟机的概念模型里

JVM内存结构(运行时数据区)

前言 Java程序的运行是通过Java虚拟机来实现的.通过类加载器将class字节码文件加载进JVM,然后根据预定的规则执行.Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些内存区域被统一叫做运行时数据区.Java运行时数据区大致可以划分为5个部分.在这里要特别指出,我们现在说的JVM内存划分是概念模型.如下图所示: JVM运行时数据区分为5种: 程序计数器 虚拟机栈(java栈) 堆 方法区 本地方法栈 程序计数器 程序计数器是一块较小的内存空间,它可

深入理解JVM:JVM执行时数据区域分类

JVM在运行java程序的过程中会把他所管理的内存划分为若干个不同的数据区域. 这些区域都有各自的用途和创建.销毁时间.有些区域随着虚拟机的启动而存在.有些区域则依赖用户线程的启动和结束而建立和销毁.依据<Java虚拟机规范1.7>规定,Java虚拟机所管理的内存分为下面几个区域: 程序计数器.Java虚拟机栈.本地方法栈.Java堆.方法区.运行时常量池.直接内存 程序计数器 是一块较小的内存空间.他能够看作是当前线程所运行的字节码的行号指示器. 在虚拟机的概念模型里,字节码解释器工作时就是

Java虚拟机 - 结构原理与运行时数据区域

http://liuwangshu.cn/java/jvm/1-runtime-data-area.html 前言 本来计划要写Android内存优化的,觉得有必要在此之前介绍一下Java虚拟机的相关知识,Java虚拟机也并不是三言两语能够介绍完的,因此开了Java虚拟机系列,这一篇文章我们来学习Java虚拟机的结构原理与运行时数据区域. 1.Java虚拟机概述 Oracle官方定义的Java技术体系主要包括以下几个部分: Java程序设计语言 各种平台的Java虚拟机 Class文件格式 Ja

Java虚拟机(一)结构原理与运行时数据区域

前言 本来计划要写Android内存优化的,觉得有必要在此之前介绍一下Java虚拟机的相关知识,Java虚拟机也并不是三言两语能够介绍完的,因此开了Java虚拟机系列,这一篇文章我们来学习Java虚拟机的结构原理与运行时数据区域. 1.Java虚拟机概述 Oracle官方定义的Java技术体系主要包括以下几个部分: Java程序设计语言 各种平台的Java虚拟机 Class文件格式 Java API类库 第三方Java类库 可以把Java程序设计语言.Java虚拟机和Java API类库这三部分

Java运行时数据区域

运行时数据区域 Java虚拟机在执行Java程序的过程中会把它管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在, 有些区域则是依赖用户线程的启动和结束而建立和销毁.如图 1.1 程序计数器 是一块内存比较小的空间.作用:用来标志当前线程所执行的字节码的行号指示器(即在字节码中添加编号).在jvm中,字节码解释器工作时就是通过改变这个计数器上的值来选取下一条需要执行的字节码指令.在分支.循环.跳转.异常处理.线程恢复等功能都需要

JVM学习笔记:Java运行时数据区域

JVM执行Java程序的过程中,会使用到各种数据区域,这些区域有各自的用途.创建和销毁时间.根据<Java虚拟机规范>,JVM包括下列几个运行时数据区域,如下图所示: 其中红色部分是线程私有的,即每个线程各自都有自己的一份.绿色部分是各个线程共享的. 1.PC寄存器(The pc Register) (1)每一个Java线程都有一个PC寄存器. (2)PC寄存器是用于存储每个线程下一步将执行的JVM指令,如该方法为native的,则PC寄存器中不存储任何信息. (3)此内存区域是唯一一个在JV