java中堆和栈的概念解析

       作为一个java程序员,面试的时候有些公司的面试官也许会问到java中堆和栈的概念。当然了,这个中高级java程序员才需要掌握的吧。初级java程序员如果可以弄明白这方面的知识,肯定也会加分。最近在面试的我就遇到了一个面试官给我出了这个问题。没有了解过的我很尴尬。回来一看才发现,也就是那么回事吧。

       本人看的概念来自于《深入理解Java虚拟机》这本书,这本书可谓是讲解JVM原理的一本圣经。

      首先,java中的堆和栈是指什么呢?这个问题说明了提问者,是将java中的内存区分为了堆内存和栈内存。这是一种粗略的分法。java的内存区域可是复杂多了,就好像楼主我在广州生活,城中村和小区房是我租房最关注的2个地方,但是广州其他地方的租房也是很复杂的。java程序员往往关注的就是堆内存和栈内存这2个区域。

      我们先来说说堆内存,java的堆是java虚拟机所管理的内存中最大的一块。这个内存的唯一目的就是存放对象实例。几乎所有的对象实例都在这里分配内存(注意不是所有啊)。所以java堆是被所有线程所共享的一块内存。在java虚拟机的规范中,java堆可以处于物理上不连续的内存空间,只要逻辑上是连续的就好。和我们的电脑磁盘空间是一样的。如果在堆中没有内存可供使用做实例分配,并且堆也没有扩展的时候,就会出现OutOfMemoryError异常。

     再来看看java 的栈内存。它的真正名称叫做:java虚拟机栈。它和java堆内存的有一个很大的区别在于,它是线程私有的。它的生命周期也和线程的生命周期捆绑在一起。 每个java方法在执行的时候都会创建一个栈帧用来存储局部变量表,操作数栈,动态链接,方法出口等信息。每一个方法从调用直至完成执行后的过程,就对应着一个栈帧在虚拟机栈中的入栈到出栈的过程。在java虚拟机栈中,局部变量表所需要的内存空间在编译期间完成分配的。也就是说在进入一个方法时,这个方法在帧中分配多大的局部变量空间是完全确定的,在方法运行期间不会改变局部变量表的大小。那如果这个方法的线程所需要的内存大于这个空间呢?结果是会抛出OutOfMemoryError异常。另外如果线程请求的栈深度大于虚拟机所设的深度,将抛出 StackOverflowError异常。

猜你喜欢

转载自blog.csdn.net/u010102390/article/details/69942531