本文从以下内容介绍java内存区域
一、运行时数据区域
一、运行时数据区域
1、线程与JVM线程
1.1、线程
此处所说的线程指程序执行过程中的一个线程实体。
JVM 允许一个应用并发执行多个线程。Hotspot JVM 中的 Java 线程与原生操作系统线程有直接的映射关系。当线程本地存储、缓冲区分配、同步对象、栈、程序计数器等准备好以后,就会创建一个操作系统原生线程。Java 线程结束,原生线程随之被回收。操作系统负责调度所有线程,并把它们分配到任何可用的 CPU 上。当原生线程初始化完毕,就会调用 Java 线程的 run() 方法。run() 返回时,被处理未捕获异常,原生线程将确认由于它的结束是否要终止 JVM 进程(比如这个线程是最后一个非守护线程)。当线程结束时,会释放原生线程和 Java 线程的所有资源。
1.2、JVM线程
后台线程与触发 public static void main(String[]) 函数的主线程以及主线程创建的其他线程一起运行。Hotspot JVM 后台运行的系统线程主要有下面几个:
虚拟机线程(VM thread) | 这个线程等待 JVM 到达安全点操作出现。这些操作必须要在独立的线程里执行,因为当堆修改无法进行时,线程都需要 JVM 位于安全点。这些操作的类型有:stop-the-world 垃圾回收、线程栈 dump、线程暂停、线程偏向锁(biased locking)解除。 |
周期性任务线程 | 这线程负责定时器事件(也就是中断),用来调度周期性操作的执行。 |
GC 线程 | 这些线程支持 JVM 中不同的垃圾回收活动。 |
编译器线程 | 这些线程在运行时将字节码动态编译成本地平台相关的机器码。 |
信号分发线程 | 这个线程接收发送到 JVM 的信号并调用适当的 JVM 方法处理。 |
2、运行时的数据区域
运行时的数据区域:
(1)线程共享的内存区域:
堆(GC堆) Heap
方法区 (Non Heap)Method Area
(2)线程私有的内存区域:
程序计数器 Program Counter Register
虚拟机栈 VM stack
本地方法栈 Native Method stack
1、程序计数器
程序计数器:为较小的一片内存区域,它的作用可以看做当前线程所执行字节码的行号指示器。虚拟机的概念模型中,字节码解释器的工作就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程回复功能都需要这个计数器来完成。
JVM的多线程通过线程轮流切换并分配处理器执行时间的方式实现的,任何确定时刻,单个处理器只会执行一条线程指令。
线程切换后能回到正确的执行位置,因此每条线程都要一个独立的程序计数器,各个线程互不干扰,因此,程序计数器为线程私有的内存区域。
线程执行的是一个java方法,则这个计数器记录的是正在执行的VM的字节码指令地址;如果执行的是Native方法,则这个计数器的值为Undefined,该区域为唯一一个在Java VM规范中没有规定任何OutOfMemoryError的区域。
2、Java VM栈
虚拟机栈为线程私有,它的声明周期与线程相同。
虚拟机栈描述的是:java方法执行的内存模型,每个方法的执行的时候都会同时创建一个栈帧(stack frame)。
栈帧:用于存储局部变量表、操作栈、动态链接、方法的出口信息、类当前方法运行时常量池的引用。
Java VM规范中,该区域有两种异常:
(1)StackOverflowError:如果线程请求的栈的深度大于虚拟机所允许的深度会抛出该异常;
(2)OutOfMemoryError:虚拟机栈可以动态扩展,当扩展无法申请到足够的内存时会抛出该异常;
3、本地方法栈
与java vm栈的功能类似;
虚拟机栈为虚拟机执行java方法(字节码服务),而本地方法栈则为虚拟机用到的native方法服务;
本地方法栈同样也会抛出StackOverflowError、OutOfMemoryError异常。
4、Java堆
VM内存管理中最大的一块区域;
Java堆为所有的线程共享,在虚拟机启动时创建;
此区域唯一的目的是存放对象的实例,几乎所有的对象实例都在该区域分配;
Java堆为垃圾回收器管理的主要区域,因此,该区域与也别成为GC堆。
5、方法区
与java的堆一样,是各个线程共享的内存区域,用于存储已被虚拟机加载的类信息、常量、静态变量、及时编译器编译后的代码等数据。该区域的别名叫做Non Heap(非堆),目的与java堆区分。
5.1、运行时常量池
方法区的一部分;
Class文件中除了有类的版本、字段、方法、接口等信息描述外,还有一项信息是常量池;
Class文件中的常量池用于存放编译器生成的各种字面量和符号引用,这部分内容在类加载后存放到方法区的运行时常量池中。
运行时常量池较之Class文件的常量池另外一个重要特征是具备动态性;
java语言并不要求常量一定只能在编译期产生,也就是说并非在Class文件中的常量池在类文件加载时进入到方法区的运行时常量池,运行期同样可以讲常量放入到池中,这种特性用的较多的是String类的intern方法;
运行时常量池为方法区的一部分,自然会受到方法区内存限制,当常量池无法申请到内存时会抛出OutOfMemoryError。
本文参考自:http://www.importnew.com/17770.html
《深入理解Java虚拟机》 周志明
相关推荐
Java内存区域和垃圾收集(GC)机制是Java编程中至关重要的一部分,它关乎程序的性能、稳定性和资源管理。本文将深入探讨Java虚拟机(JVM)中的内存划分、垃圾收集的工作原理以及相关工具的使用。 1. **Java内存区域...
1. **Heap(堆)**:这是Java中最主要的内存区域,用于存储所有的类实例和数组。当堆空间不足时,会抛出`java.lang.OutOfMemoryError: Java heap space`异常。为了优化内存管理,Java采用了垃圾回收机制(Garbage ...
java内存区域和内存溢出.xmind
Java内存区域与内存溢出异常.pdf
Java虚拟机内存区域模型是Java虚拟机管理的内存区域模型,该模型将内存区域分为程序计数器、虚拟机栈、本地方法栈、堆和方法区五个部分。程序计数器是一块较小的内存空间,用于记录当前线程执行的字节码指令地址。...
- **主内存**: 所有线程共享的内存区域,包含堆和方法区,线程间通信的媒介。 - **工作内存**: 每个线程的私有缓存,用于存储从主内存中复制的变量副本,执行计算操作后可能更新回主内存。 2. **内存间交互** - ...
Java虚拟机Java内存区域及对象.doc
Java虚拟机(JVM)中有三个主要的内存区域:堆内存(Heap)、栈内存(Stack)和方法区(Method Area)。其中,堆内存是Java对象的主要存储场所,栈内存主要存储方法调用时的局部变量,而方法区则存储类的信息,如类...
### 如何解决Java内存泄漏 #### 1. 背景 Java凭借其垃圾回收机制大大简化了内存管理,使得开发者无需手动管理内存的释放,从而提升了开发效率。然而,这种自动化管理也可能成为一把双刃剑,特别是当开发人员忽视...
#### 二、Java内存模型与内存区域 Java虚拟机(JVM)管理着多种不同类型的内存区域,包括堆内存(Heap Memory)、方法区(Method Area)、永久代(Permanent Generation Space)等。不同的内存区域有着不同的作用和特点: ...
每一个Java应用程序启动时都会创建一个独立的Java虚拟机(JVM)实例,每个JVM实例都会有自己的Java堆内存区域。 - **内存分配与回收**:当我们在代码中创建一个新的对象时,JVM会在堆内存中为其分配一块内存。当...
Java内存区域是Java虚拟机(JVM)管理内存的核心组成部分,它们主要分为以下几个部分: 1. **程序计数器(ProgramCounterRegister)**:每个线程都有自己的程序计数器,用于存储当前线程正在执行的字节码的行号指示...
下面将深入探讨这些内存区域以及相关的垃圾收集和并发收集机制。 1. **堆内存**:Java对象主要存储在堆内存中,它是所有线程共享的一块区域。堆内存由Java虚拟机(JVM)自动管理,通过新生代、老年代和永久代来划分...
本教程将涵盖Java的基础知识,特别是关于内存管理的重要概念——Java内存区域、Out of Memory (OOM)错误以及垃圾回收器和垃圾回收策略。 1. **Java入门**: Java的学习始于基础语法,包括变量、数据类型、运算符、...
JAVA内存溢出 JAVA中OutOfMemoryError(内存溢出)的三种情况及解决办法 Java中的OutOfMemoryError(内存溢出)是一种常见的错误,本文将详细介绍OutOfMemoryError的三种情况及其解决方法。 首先,我们需要了解...
### JAVA内存设置原理详解 在深入探讨JAVA内存设置原理之前,我们先理解一下JVM(Java虚拟机)的内存管理机制。JVM是JAVA运行时环境的核心,它负责执行JAVA字节码,同时管理程序运行时的内存分配与回收。JVM的内存...
这是自己读《深入理解Java虚拟机》时候用XMind建立的思维导图,目的是为了能够帮助自己整理、梳理相关的知识以及方便自己日后的回顾,帮助自己建立起关于JVM的知识体系,里边也有一些对相关内容的补充,通过备注的...
1. **堆内存**:存储所有对象实例和数组,是Java中最大的内存区域,通过`System.gc()`触发的垃圾收集主要针对这部分内存。 2. **栈内存**:每个线程都有一个独立的栈,用于存储方法调用时的局部变量、方法参数和...
Java内存分配主要涉及五个区域:寄存器、栈、堆、静态域和常量池。在Java编程中,理解这些内存区域的分配规则对于优化代码性能和避免内存泄漏至关重要。 1. **寄存器**:这是最快捷的存储区域,但不在Java程序员的...