jvm把内存划分若干不同的数据区域。
- 灰色的部分,是所有线程共享的数据区
- 白色部分,是线程独有的隔离数据区
程序计数器Program Counter Register
该区域是jvm中唯一没有规定任何内存溢出的区域,该区域用于记录当前线程正在执行的字节码行号指示器,在多线程机制下,线程间执行字节码是隔离的,都有自己的当前位置,所有该区域是线程独享的。
虚拟机栈 VM Stack
常提起的堆和栈中的栈,实际就是指的这块内存,用于存放局部变量表、操作数、方法入口等信息,当执行一个方法时,就是在不断执行入栈、出栈的过程,所以这个也是线程独享的。
有关内存溢出:
- 如果请求栈深度大于VM允许的深度时,会引发StackOverFlowError异常;
- 如果栈在动态扩展容量时,系统没有足够的内存可用,会引发OutOfMemoryError异常;
本地方法栈Native Method Stack
和VM Stack作用相同,区别是VMStack用于执行java方法,而这个用于服务本地方法。
Java堆
是JVM中内存最大的一块,也是GC主要发生的场所,这一块所有线程共享。
理论上代码中所有对象的实例(也就是你new Obejct()的地方)都要求放在这块内容中,实际上也不是那么绝对。
一般划分为新生代(Eden、From、To)、老年代。
方法区Method Area
和java堆相对,又叫非堆,用于存储jvm加载的类变量、常量、静态变量和即时编译的代码等数据。
该区域也是所有线程共享的。
有关内存溢出:
当该区域无法满足内存分配时,将引发OutOfMemoryError异常。
GC对该区域的管理,主要体现在对常量池的回收方面。
运行时常量池Runtime Constant Pool
一般常用的string.intern()会把变量写入RCP中。