JVM-运行时数据区
1.所有线程共享的
1.1方法区
在HotSpot上称为永久代。(便于同堆一起进行gc收集)
主要用于存储已被jvm加载的类信息、运行时常量池、静态变量、即时编译器编译后的代码等数据。
常量池:
存放编译期生成的各种字面量、符号引用和直接引用,类加载后进行存放。
常量池并非只存放编译期生成的常量,运行时生成的也存放,如string的intern()方法。
GC回收主要回收废弃常量和无用的类。
无法满足内存分配时抛出OutOfMemoryError异常。
1.2堆
虚拟机启动时创建,一般是最大的一块区域。
一般来说所有对象的实例和数组都在堆上分配。(新技术的发展导致并不是绝对分配在堆上)
是进行垃圾回收(GC)的主要区域。
分为新生代,老年代。
新生代:Eden,From Survivor,To Survivor。
当堆中没有剩余内存完成实例分配且堆内存无法扩展时抛出OutOfMemoryError异常。
2.线程间隔离的
这些区域是线程私有的,他们的生命周期与线程相同。
2.1虚拟机栈
java方法执行的内存模型,每个方法执行时会创建一个栈帧。
虚拟机栈中的栈帧用于存储局部变量表,操作数栈,动态连接,方法出入口信息等。
每一个方法调用与执行完成就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。
局部变量表包含:编译器可知的基本数据类型,对象引用类型,returnAddress类型。
基本数据类型:boolean、byte、char、short、int、float、long、double
对象引用类型:指向对象起始地址的指针或指向(代表对象或存储对象信息的)句柄。
returnAddress类型:指向特定指令内存地址的指针。
线程请求栈深度大于允许的深度时抛出StackOverflowError异常,如果虚拟机栈动态扩展时无法申请更多内存则抛出OutOfMemoryError异常。
2.2本地方法栈
与虚拟栈类似,不过是在执行native方法时使用的,无具体实现规定。
同虚拟机栈一样可以抛出StackOverflowError异常,OutOfMemoryError异常。
2.3程序计数器
较小的内存区,当前线程字节码行号指示器。
如果执行的是java方法存放的是字节码指令的地址,执行的是native方法此计数器为空。
小的内存区,当前线程字节码行号指示器。
如果执行的是java方法存放的是字节码指令的地址,执行的是native方法此计数器为空。
不存在OutOfMemoryError异常。