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堆中还必须包含能查找到此对象类型数据(如对象类型,父类,实现的接口,方法等)的地址信息,这些类型数据则存储在方法区中。
相关推荐
### Sun JVM原理与内存管理 #### 一、Sun JDK 1.6 GC (Garbage Collector) Sun JDK 1.6 的垃圾收集器(GC)是其内存管理的关键组成部分,它负责自动地回收不再使用的对象所占用的内存。本文将详细介绍Sun JDK 1.6 GC...
在 Java 语言中,开发者不能直接控制程序运行内存,对象的创建都是由类加载器一步步解析、执行与生成于内存区域中的。并且 JVM 有自己的垃圾回收器对内存区域管理、回收。然而,我们已经可以通过一些工具来在程序...
JVM 内存区域组成包括栈内存和堆内存。栈内存用于存放基本类型变量和对象的引用变量,而堆内存用于存放由 new 创建的对象和数组。堆的优势是可以动态分配内存大小,生存期也不必事先告诉编译器,但缺点是要在运行时...
Java堆是Java虚拟机所管理的内存中最大的一块,它是所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的是存放对象实例,几乎所有的对象实例都在这里分配内存。 - **特点**: - 线程共享。 - ...
【初探JVM内存区域】 Java虚拟机(JVM)是Java编程语言的核心组成部分,它为Java应用程序提供了运行环境。理解JVM内存区域对于优化Java应用性能至关重要。本篇文章将详细探讨JVM中的主要内存区域及其作用。 1. **...
方法区是 JVM 中的一块内存区域,用来存储类的元数据、字段、方法、常量池等信息。方法区是所有线程共享的,方法区中的数据可以被所有线程访问和共享。 运行时常量池 运行时常量池是方法区的一部分,用于存储常量...
JVM内存分为几个关键区域,每个区域都有特定的功能和作用。这些区域包括: - **程序计数器(PC Register)**:每个线程都有自己独立的程序计数器,用于记录当前线程执行的字节码的行号。在方法调用、异常处理等过程...
Java虚拟机(JVM)内存模型是Java编程中不可或缺的一部分,它主要分为以下几个分区: ...此外,了解这些内存区域的工作原理也能帮助开发者在遇到栈溢出或内存溢出等问题时,更快地定位和解决问题。
### JVM运行时数据区详解 #### 一、概述 Java虚拟机(JVM)作为Java程序的运行环境,定义了一系列用于程序执行过程中使用的数据区域。这些数据区域在JVM启动时创建,在JVM退出时销毁。其中一些数据区域是线程独立...
总结来说,JVM的运行机制是Java平台无关性的关键,它通过字节码和解释器实现了代码的跨平台执行,同时通过垃圾回收和内存管理提供了高效且安全的运行环境。理解JVM的工作原理对于优化Java应用性能、排查问题和开发...
通过 jstat,你可以监控 JVM 各个区域的内存使用率,包括年轻代、老年代和永久代,这对于分析内存泄漏和优化 GC 参数至关重要。 #### jmap:内存映射和对象转储 jmap 工具用于打印 Java 进程的堆内存布局,包括...
1. **堆内存(Heap)**:这是JVM管理的最大块内存区域,用于存储所有对象实例以及数组。堆内存又分为年轻代(Young Generation)和老年代(Old Generation),年轻代进一步细分为Eden区和两个Survivor区(S0、S1)。 2. **...
1. **堆内存(Heap)**:这是程序共享的内存区域,用于存储对象实例和数组。 2. **方法区(Method Area)**:用于存储类的信息、静态变量、常量池等数据。 3. **栈内存(Stack)**:每个线程都有一个私有的栈,用于存储...
Java虚拟机(JVM)调优与内存管理是...总的来说,JVM内存管理和调优是一项复杂的工作,需要深入理解JVM的工作机制,结合应用程序的运行特点,合理配置内存区域大小和选择适当的垃圾回收策略,以达到最佳的性能表现。
### JVM 运行时数据区域、垃圾回收机制与类加载机制详解 #### 一、运行时数据区域 Java虚拟机(JVM)的核心组件之一便是其运行时数据区域,这一区域负责存储程序运行过程中产生的各种数据。为了更好地理解这部分内容...
在实际应用中,MAT不仅限于排查内存泄漏,还可以用于优化内存配置,例如调整堆大小、新生代和老年代的比例,以及了解应用对持久代、元空间等其他内存区域的影响。同时,MAT提供的插件和扩展功能也使得分析更加灵活和...
- **堆内存**:这是JVM最大的内存区域,用于存储对象实例。堆内存分为新生代(Young Generation)、老年代(Tenured Generation)和持久代(Permanent Generation,Java 8后被元空间Metaspace替代)。 - **新生代*...
### JVM详解及运行时内存分区解析 #### JVM简介 Java虚拟机(JVM)是一种能够执行Java...通过以上分析,我们了解了JVM运行时内存分区的详细情况及其各自的特点和用途,这对于理解和优化Java应用程序的性能至关重要。
JVM(Java虚拟机)是运行Java程序的核心引擎,负责在不同操作系统上提供统一的运行环境。JVM内存管理是Java平台的一个重要特性,其内存空间的分配和回收机制对Java应用程序的性能和稳定性有着至关重要的影响。 首先...
4. **Java堆(Java Heap)**:所有线程共享的内存区域,在JVM启动时创建。它是JVM管理的最大内存区域,主要用于存放对象实例以及数组。 5. **方法区(Method Area)**:存储已被加载的类信息、常量、静态变量、即时...