`
liulanghan110
  • 浏览: 1076703 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

JVM运行时数据区结构

    博客分类:
  • JAVA
阅读更多

VM运行时数据区域

JVM执行Java程序的过程中,会使用到各种数据区域,这些区域有各自的用途、创建和销毁时间。根据《Java虚拟机规范(第二版)》(下文称VM Spec)的规定,JVM包括下列几个运行时数据区域:

 

1.程序计数器(Program Counter Register):

 

每一个Java线程都有一个程序计数器来用于保存程序执行到当前方法的哪一个指令,对于非Native方法,这个区域记录的是正在执行的VM原语的地址,如果正在执行的是Natvie方法,这个区域则为空(undefined)。此内存区域是唯一一个在VM Spec中没有规定任何OutOfMemoryError情况的区域。

 

2.Java虚拟机栈(Java Virtual Machine Stacks

与程序计数器一样,VM栈的生命周期也是与线程相同。VM栈描述的是Java方法调用的内存模型:每个方法被执行的时候,都会同时创建一个帧(Frame)用于存储本地变量表、操作栈、动态链接、方法出入口等信息。每一个方法的调用至完成,就意味着一个帧在VM栈中的入栈至出栈的过程。在后文中,我们将着重讨论VM栈中本地变量表部分。

经常有人把Java内存简单的区分为堆内存(Heap)和栈内存(Stack),实际中的区域远比这种观点复杂,这样划分只是说明与变量定义密切相关的内存区域是这两块。其中所指的后面会专门描述,而所指的就是VM栈中各个帧的本地变量表部分。本地变量表存放了编译期可知的各种标量类型(booleanbytecharshortintfloatlongdouble)、对象引用(不是对象本身,仅仅是一个引用指针)、方法返回地址等。其中longdouble会占用2个本地变量空间(32bit),其余占用1个。本地变量表在进入方法时进行分配,当进入一个方法时,这个方法需要在帧中分配多大的本地变量是一件完全确定的事情,在方法运行期间不改变本地变量表的大小。

VM Spec中对这个区域规定了2中异常状况:如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常;如果VM栈可以动态扩展(VM Spec中允许固定长度的VM栈),当扩展时无法申请到足够内存则抛出OutOfMemoryError异常。

3.本地方法栈(Native Method Stacks

本地方法栈与VM栈所发挥作用是类似的,只不过VM栈为虚拟机运行VM原语服务,而本地方法栈是为虚拟机使用到的Native方法服务。它的实现的语言、方式与结构并没有强制规定,甚至有的虚拟机(譬如Sun Hotspot虚拟机)直接就把本地方法栈和VM栈合二为一。和VM栈一样,这个区域也会抛出StackOverflowErrorOutOfMemoryError异常。


4.Java
堆(Java Heap

对于绝大多数应用来说,Java堆是虚拟机管理最大的一块内存。Java堆是被所有线程共享的,在虚拟机启动时创建。Java堆的唯一目的就是存放对象实例,绝大部分的对象实例都在这里分配。这一点在VM Spec中的描述是:所有的实例以及数组都在堆上分配(原文:The heap is the runtime data area from which memory for all class instances and arrays is allocated),但是在逃逸分析和标量替换优化技术出现后,VM Spec的描述就显得并不那么准确了。

Java堆内还有更细致的划分:新生代、老年代,再细致一点的:edenfrom survivorto survivor,甚至更细粒度的本地线程分配缓冲(TLAB)等,无论对Java堆如何划分,目的都是为了更好的回收内存,或者更快的分配内存,在本章中我们仅仅针对内存区域的作用进行讨论,Java堆中的上述各个区域的细节,可参见本文第二章《JVM内存管理:深入垃圾收集器与内存分配策略》。

根据VM Spec的要求,Java堆可以处于物理上不连续的内存空间,它逻辑上是连续的即可,就像我们的磁盘空间一样。实现时可以选择实现成固定大小的,也可以是可扩展的,不过当前所有商业的虚拟机都是按照可扩展来实现的(通过-Xmx-Xms控制)。如果在堆中无法分配内存,并且堆也无法再扩展时,将会抛出OutOfMemoryError异常。

5.方法区(Method Area

方法区可能认识它的人还不太多,如果叫永久代(Permanent Generation)它的粉丝也许就多了。它还有个别名叫做Non-Heap(非堆),但是VM Spec上则描述方法区为堆的一个逻辑部分(原文:the method area is logically part of the heap),这个名字的问题还真容易令人产生误解,我们在这里就不纠结了。

方法区中存放了每个Class的结构信息,包括常量池、字段描述、方法描述等等。VM Space描述中对这个区域的限制非常宽松,除了和Java堆一样不需要连续的内存,也可以选择固定大小或者可扩展外,甚至可以选择不实现垃圾收集。相对来说,垃圾收集行为在这个区域是相对比较少发生的,但并不是某些描述那样永久代不会发生GC(至少对当前主流的商业JVM实现来说是如此),这里的GC主要是对常量池的回收和对类的卸载,虽然回收的成绩一般也比较差强人意,尤其是类卸载,条件相当苛刻。

6.运行时常量池(Runtime Constant Pool

Class文件中除了有类的版本、字段、方法、接口等描述等信息外,还有一项信息是常量表(constant_pool table),用于存放编译期已可知的常量,这部分内容将在类加载后进入方法区(永久代)存放。但是Java语言并不要求常量一定只有编译期预置入Class的常量表的内容才能进入方法区常量池,运行期间也可将新内容放入常量池(最典型的String.intern()方法)。

运行时常量池是方法区的一部分,自然受到方法区内存的限制,当常量池无法在申请到内存时会抛出OutOfMemoryError异常。

 

7.本机直接内存(Direct Memory

直接内存并不是虚拟机运行时数据区的一部分,它根本就是本机内存而不是VM直接管理的区域。但是这部分内存也会导致OutOfMemoryError异常出现,因此我们放到这里一起描述。

JDK1.4中新加入了NIO类,引入一种基于渠道与缓冲区的I/O方式,它可以通过本机Native函数库直接分配本机内存,然后通过一个存储在Java堆里面的DirectByteBuffer对象作为这块内存的引用进行操作。这样能在一些场景中显著提高性能,因为避免了在Java对和本机堆中来回复制数据。

显然本机直接内存的分配不会受到Java堆大小的限制,但是即然是内存那肯定还是要受到本机物理内存(包括SWAP区或者Windows虚拟内存)的限制的,一般服务器管理员配置JVM参数时,会根据实际内存设置-Xmx等参数信息,但经常忽略掉直接内存,使得各个内存区域总和大于物理内存限制(包括物理的和操作系统级的限制),而导致动态扩展时出现OutOfMemoryError异常。

 

分享到:
评论

相关推荐

    JVM运行时数据区

    ### JVM运行时数据区详解 #### 一、概述 Java虚拟机(JVM)作为Java程序的运行环境,定义了一系列用于程序执行过程中使用的数据区域。这些数据区域在JVM启动时创建,在JVM退出时销毁。其中一些数据区域是线程独立...

    Java内存模型与JVM运行时数据区的区别详解

    Java内存模型与JVM运行时数据区的区别详解 Java内存模型是Java语言在多线程并发情况下对于共享变量读写的规范,主要是为了解决多线程可见性、原子性的问题,解决共享变量的多线程操作冲突问题。Java内存模型是为了...

    全面了解JVM组成底层工作原理以及数据结构

    此外,直接内存不属于JVM运行时数据区的一部分,但被频繁使用,如在Java NIO中用于基于Channel与Buffer的IO操作。 3. JVM执行引擎与垃圾回收: JVM的执行引擎负责解释字节码指令,它通常包括即时编译器和解释器两种...

    JVM运行时数据区原理解析

    JVM运行时数据区原理解析 JVM运行时数据区是Java虚拟机中最重要的组成部分之一,它是JVM运行时的核心区域,负责存储和管理程序运行时需要的数据。根据JVM规范,JVM运行时数据区可以分为五个部分:PC寄存器、虚拟机...

    JVM 运行时数据区域,垃圾回收机制,类加载机制三大功能详解.docx

    ### JVM 运行时数据区域、垃圾回收机制与类加载机制详解 #### 一、运行时数据区域 Java虚拟机(JVM)的核心组件之一便是其运行时数据区域,这一区域负责存储程序运行过程中产生的各种数据。为了更好地理解这部分内容...

    jvm的基本原理及结构

    JVM的逻辑结构主要包括类加载系统、运行时数据区、执行引擎、本地接口等部分,这些构成了Java平台的核心。 - **类加载系统**:负责将.class文件中的二进制数据读入到内存中,进行字节码解析和动态链接,最终生成可...

    JVM的运行机制

    - JVM允许在运行时动态加载类和资源,适应不同环境的需求。 总结来说,JVM的运行机制是Java平台无关性的关键,它通过字节码和解释器实现了代码的跨平台执行,同时通过垃圾回收和内存管理提供了高效且安全的运行...

    03 运行时数据区概述及线程.pptx

    03 JVM 运行时数据区概述及线程的 PPT 重绘。讲述 Java 虚拟机 运行时数据区所处位置,结构划分,以及各个区域与线程的关系。

    JVM运行时数据区划分原理详解

    "JVM运行时数据区划分原理详解" JVM运行时数据区划分原理详解是Java虚拟机(JVM)的核心组件之一,负责管理Java应用程序的内存资源。该原理详解了JVM如何划分和管理内存空间,以便更好地支持Java应用程序的运行。 ...

    面试资料.zip(并发编程\数据结构和算法\jvm运行时内存)

    在准备面试时,掌握Java相关的并发编程、数据结构与算法以及JVM运行时内存是非常关键的。这份"面试资料.zip"包含了一系列与这些主题相关的学习材料,如PDF文档和XMind思维导图,旨在帮助你深入理解并熟练应用这些...

    搜索引擎创建索引时JVM 运行时内存溢出解决方案

    综上所述,解决JVM运行时内存溢出问题需要从多个角度进行:合理调整JVM内存参数、优化索引构建算法、监控系统状态并进行必要的硬件升级,甚至考虑采用分布式计算。只有这样,我们才能确保搜索引擎在创建索引时高效、...

    JVM内存结构.pdf

    2. **运行时数据区**:即通常所说的JVM内存结构,包括方法区、堆、栈、本地方法栈和程序计数器。 3. **执行引擎**:解释或编译Java字节码并执行。 #### 三、运行时数据区详解 ##### 1. 方法区(Method Area) - **...

    深入JVM内核—原理、诊断与优化视频教程-2.JVM运行机制

    【JVM运行机制详解】 Java虚拟机(JVM)是Java平台的核心组成部分,它负责执行字节码,为Java程序提供跨平台的运行环境。在深入理解JVM内核的运行机制时,我们需要关注以下几个关键点: 1. **类加载机制**:JVM...

    运行时数据区域

    本文将围绕JVM运行时数据区域进行详细介绍,包括程序计数器、Java虚拟机栈、本地方法栈、方法区以及Java堆等组成部分。 #### 二、程序计数器 **定义**:程序计数器是一块较小的内存空间,它可以被视为当前线程所...

    解析JVM内存结构和6大区域

    JVM 的内存结构可以分为 6 个区域:PC 寄存器、JVM 栈、堆(Heap)、方法区、运行时常量池和直接内存。每个区域都有其特定的功能和作用,以下是对每个区域的详细介绍: PC 寄存器(PC Register) PC 寄存器是一块...

    很入理解JVM体系

    部分章节如下,内容在附件里面大家随意下载,欢迎...3、运行时数据区 4、本地库接口 2.3、JVM内存参数调整及监控 1、JVM之内存调整 2、JVM监控工具之Jconsole 3、JVM监控工具之JProfile 加群:113035529 共同交流学习

    JVM 工作原理

    JVM的生命周期 JVM的体系结构 JVM类加载器 JVM执行引擎 JVM运行时数据区 JVM垃圾回收 问题

    深入理解JVM内存结构及运行原理全套视频加资料

    包括JVM执行过程、虚拟机类加载机制、运行时数据区、GC、类加载器、内存分配与回收策略等,全套视频加资料高清无密码  第1讲 说在前面的话 免费 00:05:07  第2讲 整个部分要讲的内容说明 免费 00:06:58  第3讲...

    小菜鸟系列-JVM体系结构

    2. **运行时数据区(Runtime Data Area)** JVM内存分为多个区域,包括方法区、堆、虚拟机栈、本地方法栈和程序计数器。 - **方法区**:存储类信息、常量、静态变量等,Java 8后引入了元空间(Metaspace)取代了...

Global site tag (gtag.js) - Google Analytics