定义

Java虚拟机把所管理的内存划分为不同的区域,总称为运行时数据区域。

数据区域用途各不相同,有的随虚拟机启动而存在,有的随线程的生命周期存在。

根据《Java虚拟机规范(Java SE7版)》规定,Java虚拟机将数据区域划分为:程序计数器、Java虚拟机栈、本地方法栈、Java堆、方法区(运行时常量池)

程序计数器

线程私有,每个线程都有一个用来记录字节码执行位置。

一块内存区域,java虚拟机规范中唯一没有规定OutOfMemoryError的区域。

• java字节码解释器通过改变计数器的值实现分支、跳转、循环、异常处理、线程恢复等操作。

• 如果执行的是Java方法,则存储的是虚拟机字节码指令地址;如果是Native方法,则存储为空。

Java虚拟机栈

• 所谓的栈内存指的就是Java虚拟机栈。

Java方法的运行,都会生成一个栈帧,用来存储执行Java方法的局部变量、操作数栈、动态链接、方法出口等信息。

一个Java方法的执行到结束,对应为一个栈帧的出栈与入栈

• 虚拟机栈可以为固定内存,也可动态扩展。如果线程请求栈深度大于虚拟机深度,则会报StackOverflowError;如果动态扩展时无法申请到足够内存,则会报OutOfMemoryError

本地方法栈

• 与Java虚拟机栈类似,但是是为Native方法的执行提供服务。

• 也会抛出StackOverflowError与OutOfMemoryError。

Java堆

各线程共享区域

• 是java虚拟机管理的最大的一块内存区域。

是Java对象实例存储的空间

• 是垃圾收集器主要工作区域。

• 存储空间逻辑上连续,物理上可以不连续。

• 可设置为固定大小或动态扩展,如果动态扩展时无法申请到足够内存,则会报OutOfMemoryError

方法区

各线程共享区域

• 用于存储已被Java虚拟机加载的类信息,常量,静态变量、即时编译器编译后的代码等

• 方法区无法内存分配需求时,会抛出OutOfMemoryError

运行时常量池

• 是方法区的一部分。

Class类文件中有一项是常量池,用来存放编译期生成的字面量和符号引用

• 类加载后常量池存储在方法区内的运行时常量池

• 具有动态性,非编译期间的新的常量也可放入运行时常量池中。

直接内存

• 不是Java虚拟机规范定义的内存区域。

• JDK1.4后新加入的NI/O(New Input/Output)类,引入了仅与通道(Channel)与缓存。(Buffer)的I/O方式,可以直接通过Native函数库分配堆外内存。

• 内存收到本机总内存及处理器寻址空间的限制。直接内存无法内存分配需求时,会抛出OutOfMemoryError

参考:

深入理解java虚拟机