一个Java程序在虚拟机运行的过程中,在内存中需要保存很多种类型的数据。不同类型的数据,其使用方式和生命周期都不相同。为了更好地管理这些不同类型数据,jvm将自己的内存空间划分为五大区域,各个区域针对不同类型的数据,其内存空间有不同的管理方式。
这五大区域,示意图如下:
1、JVM栈(以后简称栈,stack):
描述的是Java的(普通)方法执行时所占的内存模型。程序运行时调用方法的代价是:方法中有局部变量需要开辟空间存储,方法的执行过程会产生中间变量,方法执行完毕还需要存储返回地址等等。JVM栈正是Java的(普通)方法执行时所占用的内存空间, 局部变量会直接存储在栈帧中。
于是,方法的执行流程,在JVM内存中,就变成下面这样:
每当Java程序执行一个方法,都会在栈上分配一块只属于该方法的内存区域,称之为栈帧
每当Java程序执行一个方法,都会将一个存储该方法信息的栈帧压入栈中,称之为方法进栈
方法进栈的同时局部变量开辟内存空间存储值,局部变量生效。
当方法执行完毕后,该方法的栈帧随之销毁,称之为方法的出栈
方法栈帧被销毁的同时,局部变量也被销毁,局部变量失效。
注:栈中只有处于栈顶的栈帧才会生效,表示正在执行的方法。称之为当前栈帧,当前方法。
2、堆(heap):
堆是JVM内存中最大的一块,new出来的东西(称之为对象或者实例)都在堆上。 所以new关键字的语义就是:在堆上开辟一片空间给相应的对象。而这片空间(对象)是有内存地址的,这个内存地址是留给外界访问用的。
注:引用数据用比较运算符比较的地址就是这个地址,即比较对象的内存地址。
3、方法区(method area):
面向对象详细讲。
4、本地方法栈:
和JVM栈类似,区别是本地方法栈是给本地(native)方法使用的,而不是普通方法。
5、程序计数器:
JVM执行代码解释执行的,即是一行一行执行字节码的,程序计数器用来记录当前执行的行数。
很明显,在JVM内存模型中,相对比较重要的,即和程序的执行联系更紧密的是:堆和JVM栈。堆内存用来存储对象,由于Java是面向对象语言,Java面向对象程序中将会有非常多的对象,所以堆内存主要决定了Java程序的数据如何存储的问题。而JVM栈用来表示方法的执行流程,它决定了程序如何执行,或者说如何处理数据。