为什么要进行JVM运行内存划分呢?
通过定义划分不同特性和作用的内存区域,能够更加方便高效管理内存。(个人理解,如有错误,希望指正)
JVM运行内存划分图解:
1、JVM虚拟机栈
1.1、栈是一种先进后出的数据存储结构。
1.2、java方法是基于栈模型运行的,每一个方法从调用到执行完成都都对应着一个贞栈在虚拟机栈中入栈和出栈的过程,在方法出栈时栈空间自动释放,所以栈空间使用具有高效性。
1.3、方法贞栈中主要存储局部变量表、操作数栈、动态链接、方法出口等。
1.4、栈是有深度和大小限制的,栈深度大于虚拟最大栈深度异常(StackOverFlowError),栈内存溢出异常(OutOfMemoryError)。
1.5、线程私有。
2、本地方法栈
2.1、类似JVM栈,属于虚拟机本地方法运行区。
2.2、超过栈是有深度和大小限制时也会发生StackOverFlowError和OutOfMemoryError异常。
2.3、线程私有
3、程序计数器
3.1、存放当前线程所执行的字节码行号指示器,类似于C语言中的指针。
3.2、未定义任何的内存溢出异常。
3.3、线程私有
4、方法区
4.1、主要存放被虚拟机加载的类信息、常量、静态变量、及时编译后的代码等数据。
4.2、此区域会存在垃圾回收,但回收效率不高。
4.3、当内存使用超过方法区定义的内存大小时会发生OutOfMemoryError异常。
4.4、线程共享。
5、java堆
5.1、绝大多数对象和数组都在此内存区域保存。
5.2、垃圾回收的主要区域。
5.3、超过对内存限定大小时会发生OutOfMemoryError异常。
5.4、线程共享。
6、直接内存
6.1、直接内存不属于虚拟机运行时数据区,是使用Native函数库直接分配的对外内存,然后通过一个存储在Java堆中的DirectByteBuffer对象作为这块内存的引用进行操作。这样能在一些场景中提高性能,避免了在Java堆和Native堆中来回复制数据(NIO中常用)。
6.2、此区域虽然不受Java运行时内存大小限制,但受计算机本身物理内存限制,所以也会存在OutOfMemoryError异常。