Java内存区域
根据《Java虚拟机规范 第2版》的规定,Java虚拟机所管理的内存包括以下几个运行时数据区:程序计数器,Java虚拟机栈,本地方法栈,Java堆,方法区。程序计数器,Java虚拟机栈,本地方法栈是线程私有,Java堆,方法区是线程共享。
1 程序计数器
程序计数器是一块较小的内存区域,它的作用可以看做是当前线程所执行的字节码的行号指示器。
在虚拟机的概念模型里,字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分 支,循环,跳转,异常处理,线程回复等基础功能都要依赖这个计数器来完成。
此内存区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域。
2 Java虚拟机栈
虚拟机栈描述的是Java方法执行的内存模型:每个方法被执行的时候都会同时创建一个栈帧用于存储局部变量表,操作栈,动态链接,方法出口等信息。每一个方法被调用直至执行完成,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。
请求栈深度过大将抛出StackOverflowError异常,扩展时无法申请到足够的内存将抛出OutOfMemoryError异常。
栈帧是用于支持虚拟机进行方法调用和方法执行的数据结构,一个栈帧需要分配多少内存,不会受到程序运行期变量数据的影响。
2.1 局部变量表
局部变量表存放编译期可知的各种基本数据类型(boolean,byte,char,short,int,long,float,double),对象引用(reference类型,与对象位置相关)和returnAddress类型(指向一条字节码指令的指针)。
虚拟机通过索引的方式使用局部变量表。在方法执行时,虚拟机是使用局部变量表完成参数值到参数变量列表的传递过程的。
2.2 操作数栈
虚拟机的解释执行引擎称为“基于栈的执行引擎”,这里的“栈”就是操作数栈
2.3 动态链接
每个栈帧都包含一个指向运行时常量池中该栈帧所属方法的引用,持有该引用是为了支持方法调用过程中的动态引用
2.4 方法放回地址
方法正常退出时,调用者的PC计数器的值就是可以作为返回地址,栈帧中很可能就会保存这个计数器值,而方法异常退出时,返回地址是要通过异常处理器表来确定,栈帧一般不会这部分信息。
方法退出的过程实际上等同于把当前栈出栈,因此退出时可能执行的操作有:回复上层方法的局部变量表和操作数栈,把返回值压入调用者的栈帧的操作数栈中,调用PC计数器的值以指向方法调用指令后面的一条指令。
3 本地方法栈
本地方法栈为虚拟机执行Native方法服务,虚拟机规范对本地方法栈中的方法使用的语言,使用方式与数据结构并没有强制规定。甚至有的虚拟机(Sun HotSpot虚拟机)直接把本地方法栈和虚拟机站合二为一。
与虚拟机栈一样,本地方法栈也会抛出StackOverflowError异常和OutOfMemoryError异常。
4 Java堆
Java虚拟机规范中描述的是:所有的对象实例以及数组都要在堆上分配。Java虚拟机规范的规定,Java堆可以处于物理上不连续的内存空间中,只要逻辑上是连续的即可。
从内存回收角度看,Java堆可以分为:新生代,老年代,永久代(在Sun HotSpot JVM中这个区域将会被放弃)
新生代:Eden,Form Survivor,To Survivor(在Sun HotSpot JVM中三个区域的比例分配为8:1:1)
5 方法区
用于存储已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据。Java虚拟机把方法区描述为堆的一个逻辑部分。
垃圾收集在这个区域是比较少出现的,但并不是数据进入方法区就如同永久代的名字一样“永久”存在了。这个区域的内存回收主要是针对常量池的回收和对类型卸载,一般来说这个区域的回收“成绩”比较难以令人满意,尤其是类型的卸载,条件相当苛刻,但是这部分区域的回收确实是有必要的。
运行时常量池
运行时常量池是方法区的一部分,类加载后存放编译器Class文件中的各种字面量和符号引用。
运行期间也可以将新的常量放入常量池中,如String的intern()方法.
分享到:
相关推荐
### JAVA内存分区与C/C++内存分区的深度解析 #### JAVA内存分区 在JAVA中,JVM(Java虚拟机)的内存主要分为三个区域:堆(heap)、栈(stack)和方法区(method)。每个区域都有其特定的功能和管理机制。 1. **...
Java内存区域和垃圾收集(GC)机制是Java编程中至关重要的一部分,它关乎程序的性能、稳定性和资源管理。本文将深入探讨Java虚拟机(JVM)中的内存划分、垃圾收集的工作原理以及相关工具的使用。 1. **Java内存区域...
本教程将涵盖Java的基础知识,特别是关于内存管理的重要概念——Java内存区域、Out of Memory (OOM)错误以及垃圾回收器和垃圾回收策略。 1. **Java入门**: Java的学习始于基础语法,包括变量、数据类型、运算符、...
Java内存区域是Java虚拟机(JVM)管理内存的核心组成部分,它们主要分为以下几个部分: 1. **程序计数器(ProgramCounterRegister)**:每个线程都有自己的程序计数器,用于存储当前线程正在执行的字节码的行号指示...
java内存区域和内存溢出.xmind
Java内存区域与内存溢出异常.pdf
Java 内存区域, 垃圾收集, 内存分配与回收策略, JVM 调优, 文件结构, 类加载机制, Java 程序 Java是一种面向对象的编程语言,由Sun Microsystems于1995年推出。它是一种跨平台的语言,意味着可以在不同的操作...
Java虚拟机Java内存区域及对象.doc
深入理解Java虚拟机-Java内存区域透彻分析(序列化、反序列化概念及其使用场景+实现序列化的方式+transient关键字) Java序列化和反序列化是Java虚拟机中的一种重要机制,它们可以将Java对象转换为二进制数据,然后...
1. **Heap(堆)**:这是Java中最主要的内存区域,用于存储所有的类实例和数组。当堆空间不足时,会抛出`java.lang.OutOfMemoryError: Java heap space`异常。为了优化内存管理,Java采用了垃圾回收机制(Garbage ...
Java内存区域的使用详解主要涵盖了五个核心部分:程序计数器、虚拟机栈、本地方法栈、Java堆以及方法区。这些区域各自负责不同的任务,共同确保Java应用程序的正常运行。 1. **程序计数器**:每个线程都有自己的...
这是自己读《深入理解Java虚拟机》时候用XMind建立的思维导图,目的是为了能够帮助自己整理、梳理相关的知识以及方便自己日后的回顾,帮助自己建立起关于JVM的知识体系,里边也有一些对相关内容的补充,通过备注的...
#### 二、Java内存区域概述 Java程序在运行时会根据不同的数据类型和生命周期将其分配到不同的内存区域。这些内存区域主要包括: 1. **寄存器**:用于临时存放CPU计算过程中产生的中间结果,这部分内存不由程序员...
#### 一、Java内存区域划分 Java的内存管理机制将内存分为以下几个区域: 1. **栈(Stack)**: - 存储局部变量(如基本类型的变量和对象的引用)。 - 每个线程拥有一个独立的栈。 - 栈内存中的数据在方法执行...
- **主内存**: 所有线程共享的内存区域,包含堆和方法区,线程间通信的媒介。 - **工作内存**: 每个线程的私有缓存,用于存储从主内存中复制的变量副本,执行计算操作后可能更新回主内存。 2. **内存间交互** - ...
Java虚拟机(JVM)中有三个主要的内存区域:堆内存(Heap)、栈内存(Stack)和方法区(Method Area)。其中,堆内存是Java对象的主要存储场所,栈内存主要存储方法调用时的局部变量,而方法区则存储类的信息,如类...
"浅谈Java内存区域划分和内存分配策略" 本文将详细讲述Java内存区域划分和内存分配策略,涵盖程序计数器、虚拟机栈、本地方法栈、堆、方法区等内存区域的概念和作用,以及对象创建过程和内存分配策略。 程序计数器...
### 如何解决Java内存泄漏 #### 1. 背景 Java凭借其垃圾回收机制大大简化了内存管理,使得开发者无需手动管理内存的释放,从而提升了开发效率。然而,这种自动化管理也可能成为一把双刃剑,特别是当开发人员忽视...
#### 一、Java内存区域划分 Java程序在运行过程中涉及的内存主要分为两大类:栈内存和堆内存。 1. **栈内存**:主要用于存储局部变量,如基本数据类型变量(int、long、char等)以及对象的引用变量。这些变量在...
这些区域在Java内存模型中同样占有重要地位,但在“java实现内存动态分配”的上下文中,主要关注堆和栈的动态分配。 综上所述,Java实现内存动态分配涉及到对堆内存、栈内存的理解,以及对垃圾回收机制的掌握。通过...