首先还是要摆上这张很经典的区域图。
运行时的内存大致可以分为以下5个部分。
1、程序计数器
- 程序计数器可以看成是字节码的行号指示器。
- 指令的顺序执行和跳转执行(循环,分支等),都是通过改变和读取程序计数器执行的。是不是很像计组里面的PC?
- 计数器是线程私有的,各线程之间的计数器相互独立。线程之间切换后,还能接着往下执行,靠的就是读取计数器
- 如果线程执行的是Java方法,那么它记载的是虚拟机字节码;如果执行的是Native方法,它的记载值是空。
2、虚拟机栈
- 它也是线程私有的,主要负责处理方法的执行。
- 当线程执行方法时,JVM会维护一个堆栈,堆栈里压的是每个方法的信息----栈帧。
栈帧里面包括局部变量表,操作数栈等等
- 局部变量表是栈帧里的重点。它负责存取局部变量中的基本数据类型,引用类型(不是对象本身)以及returnAddress类型
3、本地方法栈
- 和虚拟机栈非常相似
- 唯一的区别:虚拟机栈为Java方法服务,本地方法栈为Native方法服务
4、堆
- 它是线程共享的,作用是存放对象实例和数组
- 成员变量就在堆中存储和定义
- 它是GC管理的主要目标,这里不作详细叙述
5、方法区
- 主要负责存储类型信息,静态变量,常量等。
- 常量池:在1.6之前,存在于方法区中。从1.7开始,放到了堆中。
一般对于一个变量而言,栈中存放的是一个引用,堆中存放的是它的实例,而方法区中存放的是类型信息。
还有好多没写,待更
参考:
Java内存区域——堆,栈,方法区等
方法区详解
Java内存图以及堆、栈、常量区、静态区、方法区的区别
java堆、栈、堆栈,常量池的区别,史上最全总结
StringTable详解