简述Java内存区域

概述

本文将介绍Java虚拟机(JVM)内存的各个区域,了解虚拟机是怎样使用内存的。

运行时数据区域

根据虚拟机规范,虚拟机所管理的内存将会包括以下几个运行时数据区域,如下图所示。

简述Java内存区域

  • 线程独占:每个线程都会有它独立的空间,随线程生命周期而创建和销毁
  • 线程共享:所有线程能访问这块内存数据,随虚拟机或者GC而创建和销毁

方法区

方法区用于存储已被虚拟机加载的类信息、常量、静态变量、编译后的代码等数据。方法区只是虚拟机规范重的一个逻辑区划,具体的实现不受规范约束。如:

  • HotSpot在java7中将方法区放在永久代(使用永久代实现方法区),通过GC机制进行管理
  • HotSpot在java7中将方法去存储在元数据空间,通过GC机制进行管理

堆内存

Java堆由虚拟机启动时创建,唯一的目的就是存放对象实例。也因为Java堆是垃圾收集器管理的主要区域,因此很多时候也称为“GC堆”。由于收集器采用分代收集算法,堆内存还可以细分为:老年代、新生代(Eden、From Survivor、To Survivor)

虚拟机栈

Java虚拟机栈是线程私有的,每一个线程都在空间有一个私有的空间,它的生命周期和线程相同。虚拟机栈描述的是Java方法执行的内存模型,每个方法在执行的同时都会创建一个栈帧。栈帧内容包含:局部变量表、操作数栈、动态连接、方法放回地址、附加信息等。

本地方法栈

本地方法栈和虚拟机栈功能类似,虚拟机栈是为虚拟机执行Java方法而准备的,本地方法栈是为虚拟机使用Native本地方法而准备的。

程序计数器

为了线程线程切换后能恢复到正确的执行位置,每条线程都需要一个独立的程序计数器,线程间互不影响。程序计数器可以看作是当前线程所执行的字节码的行号指示器,记录当前线程执行字节码的位置,存储的是字节码指令地址,如果是Native方法,这个计数器值为空。