前言

Java 内存结构和正常程序的内存结构区别还是蛮大的,下面整理一下:

内存结构划分

运行时数据区:

  • 方法区——类信息、常量、静态变量、即时编译器编译后的代码

  • 虚拟机栈——Java 方法(局部变量表、操作数栈、动态链接、方法出口)

  • 本地方法栈——Native 方法

  • 堆——对象实例和数组

  • 程序计数器——虚拟机字节码指令的地址或 Undefined

01 虚拟机栈

线程私有的。

局部变量表

局部变量表中存放了各种基本数据类型,以及对象的引用,和函数返回地址。

局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时,这个方法在帧中分配的局部变量空间大小事完全确定的,在运行期间不会改变。

局部变量表最基本的存储单元是 slot,32 位占用一个 slot,64 位(long 和 double)占用两个 slot。

02 堆

Java 堆是被所有线程共享的一块内存区域。此区域的唯一目的就是存放对象实例。

03 方法区

也是线程共享的。

常量池

常量池表在 class 文件中,存放着编译器生成的字面量和符号引用。

  • 字面量:包括——文本字符串、八种基本类型的值,声明为 final 的常量。

  • 符号引用:包括——类和接口的全限定名、字段的名称和描述符、方法的名称和描述符。

运行时常量池是方法区的一部分,每个类都有一个。注意运行期间也有可能将新的常量放入池中。

注意:字符串常量值存的是引用值,而不是具体的实例对象,具体的实例对象是在堆中开辟的一块空间存放的。


参考资料:

  1. Java内存结构分析 https://blog.csdn.net/u010257931/article/details/131517102

  2. 一文详解JVM内存结构 https://zhuanlan.zhihu.com/p/645491975