JVM的内存空间分为三大部分:堆内存、方法区、栈内存。栈内存可以细分为java虚拟机栈和本地方法栈,堆内存可以划分为新生代和老年代。其中一部分是线程共享的,包括java堆和方法区;另一部分是线程私有的,包括虚拟机栈和本地方法栈,以及程序计数器这一部分内存。
堆内存是java虚拟机所管理的内存中最大的一块。java堆是被所有线程共享的一块内存区域,在虚拟启动时创建,目的是存放对象实例。
方法区用于存储虚拟机加载的类信息、常量、静态变量、是各个线程共享的内存区域。随着JDK8的到来,JVM不再有 永久代。但类的元数据信息还在,只不过不再是存储在连续的堆空间上,而是移动到叫做“metaspace”的本地内存)。
虚拟机栈描述的是java方法执行的内存模型:每个方法被执行的时候都会创建一个"栈帧",用于存储局部变量表(包括参数)、操作栈、方法出口等信息。每个方法被调用到执行完的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。
本地方法栈与虚拟机栈所发挥的作用是非常相似的,其区别不过是虚拟机栈为虚拟机执行Java方法服务,而本地方法栈则是为虚拟机使用到的Native方法服务。
程序计数器是用于标识当前线程执行的字节码文件的行号指示器。多线程情况下,每个线程都具有各自独立的程序计数器,所以该区域是非线程共享的内存区域。当执行java方法时候,计数器中保存的是字节码文件的行号;当执行Native方法时,计数器的值为空。
只有程序计数器不会出现内存溢出