Java运行时数据区域
分为方法区、堆、虚拟机栈、本地方法栈、程序计数器五部分。
其中方法区和堆是线程共享的,虚拟机栈、本地方法栈、程序计数器是线程独占的。
下面分别来解释一下这几个区域:
程序计数器
程序计数器记录线程执行到那个位置了,这样在进行线程切换时就可以接着上次执行的位置继续执行。
虚拟机栈
有时人们常把java内存区域划分为堆和栈,虽然这种粗略的划分不精确,但这里的栈就是指的虚拟机栈。
它也是线程独享的,即每个线程都有自己的虚拟机栈。包括局部变量表、操作数栈等
当java方法执行时就会请求一片虚拟机栈用于保存方法的局部变量等。局部变量表保存方法的基本类型数据(byte,short,char,int,long,boolean,float,double)和引用(reference)。这些都是在编译期间就知道大小的。
异常:线程请求的栈深度大于虚拟机运行的深度,StackOverflowError
栈是可以扩展大小的,扩展时无法申请到足够的空间,OutOfMemoryError
本地方法栈
与虚拟机栈类似,只不过是用于native的方法的栈。
堆
保存对象的地方,内存大小最大。
分为新生代和老年代。新生代又分为Eden空间,From Survivor空间、To Survivor空间。
堆的大小是可扩展的,通过参数-Xmx和Xms控制。
以后将要讨论的回收算法也是针对这个区域的。
方法区
是线程间共享的,用于存储类信息、常量、静态变量等。别名Non-Heap(非堆)
运行时常量池是它的一部分,用于存放编译期生成的各种字面量和符号引用(?)什么是符号引用?