jvm内存模型共分为虚拟机栈、本地方法栈、堆、方法区和程序计数栈五个部分。
1.程序计数器(线程私有):每个线程都有一个独立的程序计数器,计数器所记录的是虚拟机字节码指令当前的地址。
2.虚拟机栈(线程私有):每个线程对应一个虚拟机栈,栈中的每一个栈帧对应一个方法。它的生命周期与线程相同。每个方法被执行时都会创建一个栈帧用于存储局部变量表,操作数栈,动态链接和方法返回地址等信息。每个方法被调用直至执行完成的过程就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。
2.1局部变量表:存放了编译器可知的各种基本数据类型(int,long,short,double,float,char,byte,boolean)、对象引用(reference类型)和returnAddress类型(指向一条字节码指令的地址)。同时在编译器就确定了局部变量表的最大容量。
2.2操作数栈:虚拟机把操作数栈作为它的工作区——大多数指令都要从这里弹出数据,执行运算,然后把结果压回操作数栈。
2.3动态链接:每个栈帧都包含一个指向运行时常量池中该栈帧所属方法的引用,持有这个引用是为了支持方法调用过程中的动态连 接。
2.4方法返回地址:当方法被执行后,退出方法有两种:遇到返回字节码指令或者产生异常,并且异常没有在该方法体内得到处理。但无论哪种退出方式都需要返回被调用位置,正常退出时,一般使用栈帧中保存的地址,异常退出时则由异常处理表来确定返回地址。
3.本地方法栈(线程私有):和虚拟机栈类似,但主要为虚拟机使用到的Native方法服务。
4.Java堆(线程共享):所有线程共享,在虚拟机创建时启动,用于存放对象的实例。
堆是JVM内存占用最大,管理最复杂的一个区域。唯一的途径就是存放对象实例:所有的对象实例以及数组都在堆上进行分配。
5.方法区(线程共享):所有方法线程共享的一块内存区域,用于存储已经被虚拟机加载的类信息,常量,静态变量等。