您的位置:首页 > 编程语言 > Java开发

Java内存区域

2016-08-14 19:21 218 查看
1.运行时数据区域

运行时数据区域分为:方法区 、虚拟机栈、本地方法栈、堆、程序计数器。

(1)程序计数器: (线程私有的内存)是一块较小的内存空间,它可以看作是线程所执行的字节码的行号指示器。这个内存区域是唯一一个在Java虚拟机规范中没有规定
任何OutOfMemoryError情况的区域。

每条线程都有一个独立的程序计数器,各条线程之间程序计数器互不影响,独立存储。

(2)Java虚拟机栈:
(线程私有的内存)描述的是Java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧用于存储局部变量表、操作数栈、动态链表、方法出
口等信息。每一个方法从调用直到执行完成的过程,就对应着一个栈帧在虚拟机中入栈到出栈的过程。

通常所说的将Java内存区域划分为堆和栈,这个栈指的就是局部变量表。局部变量表存放了编译期间可知的各种基本数据类型、对象引用和
returnAddress类型。局部变量表所需的内存在编译期间就是完全确定并且分配的,方法运行期间不会改变大小。

对Java虚拟机栈对定了两种异常状况:

1.如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOveflowError异常。

2.如果虚拟机栈可以动态扩展,如果扩展时无法申请到足够的内存,就会抛出OutOfMemoryError异常。

(3)本地方法栈:
本地方法栈与Java虚拟机栈作用相似,区别是:Java虚拟机栈是为虚拟机执行Java方法,也就是字节码服务,而本地方法栈是为虚拟机所用到的
Native方法服务。其对使用的语言、使用方法和数据结构没有强制规定,甚至有的虚拟机直接就把本地方法栈和Java虚拟机栈合二为一。

本地方法栈也会抛出StackOverflowError和OutOfMemoryError异常。

(4)Java堆:
(是被所有线程共享的一块内存区域)是Java虚拟机所管理的内存中最大的一块,在Java虚拟机启动时创建。此区域的唯一目的就是存放实例对象。

如果在堆中没有内存完成实例分配,并且堆也无法再扩展时,将会抛出OutOfMemoryError异常。

(5)方法区:(各个线程共享的内存区域)存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

Java虚拟机对方法区的限制非常宽松,除了和Java堆一样不需要连续的内存和可以选择固定大小或者可扩展外,还可以选择不实现垃圾收集。此区域的内存
回收目标主要是针对常量池的回收和对类型的卸载。

当方法区无法满足内存分配需求时,将抛出OutOfMemoryError异常。

运行时常量池:
是方法区的一部分。用于存放编译期生成的各种字面量和符号引用。Class文件中除了有类的版本、字段、方法、接口等描述信息外,还有就是常量池。
Java虚拟机对于运行时的常量池没有做任何细节的描述。一般来说,除了保存Class文件中描述的符号引用外,还会把翻译出来的直接引用也存储在运行
时常量池中。运行时常量池对于Class文件常量池的梁歪一个重要特征是具备动态性。

当常量池无法再申请到内存时候会抛出OutOfMemoryError异常。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: