java内存

#1. PC

每个线程都有自己独立的程序计数器.
JVM规范中规定:
如果线程执行的是非native方法,则PC中保存的是当前需要执行的指令地址;
如果线程执行的是native方法,则PC中的值undefined。

#2. Java虚拟机栈

存放的是栈帧. 每个方法生成一个栈帧.
栈帧中包括:局部变量表、操作数栈、动态连接、方法返回地址、附加信息.
##(1) 局部变量表:
各种基本数据类型,对象引用.
这个区域的两种异常:stackOverFlowError,OutOfMemoryError
1.如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常;
2.如果虚拟机栈可以动态扩展(当前大部分的Java虚拟机都可动态扩展,只不过Java虚拟机规范中也允许固定长度的虚拟机栈),如果扩展时无法申请到足够的内存,就会抛出OutOfMemoryError异常。

##(2) 操作数栈
略.

##(3) 动态连接

每个栈帧都包含一个指向运行时常量池中该栈帧所属方法的引用(指向运行时常量池:在方法执行的过程中有可能需要用到类中的常量),持有这个引用是为了支持方法调用过程中的动态连接.

##(4) 方法返回地址

当一个方法执行完毕之后,要返回之前调用它的地方,因此在栈帧中必须保存一个方法返回地址。(PC)

##(5) 附加信息

取决于具体的虚拟机实现.在实际开发中,一般会把动态连接,方法返回地址与其它附加信息全部归为一类,称为栈帧信息。

3. 本地方法栈

执行非java代码. 其他类似,也抛stackoverflow和outOfMemory.

4. 堆

所有线程共享.
所有对象分配的地方.

5. 方法区

所有线程共享.
存储已被虚拟机加载的类信息、常量、静态变量、以及编译器编译后的代码.

常量池

运行时常量池是方法区的一部分。
Class文件中除了有类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池(Constant Pool Table),用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的运行时常量池中存放。

推荐文章