浅谈Java中的栈和堆

来源:互联网 发布:阿里云账号注销 编辑:程序博客网 时间:2024/05/20 13:19

1、前言

         一般在刚开始接触“栈”和“堆”这两个概念的时候,很多人都会产生较多的疑问,什么是栈,什么是堆,栈和堆有什么区别?更糟糕的是,数据结构中也有栈和堆这两个概念。在这种情况下,不免会让很多人更加费解前面的问题。事实上,我们这里要讲的栈和堆,跟数据结构中的栈和堆是完全不同的概念。本篇博文要讨论的栈和堆,是Java内存分配所涉及到的两个内存区域。

2、栈和堆的概念

        为了不和数据结构中的栈和堆混淆。本篇博文把Java中的栈称为“栈内存”,把堆称为“堆内存”。

        栈内存主要用于存放局部变量和方法调用。局部变量指的是那些在方法中定义的基本类型变量和引用类型变量(即对象的引用变量)。当在一段代码块中定义一个变量时,Java就会在栈中为这个变量分配内存空间,当超过变量的作用域后,Java会自动释放掉为该变量分配的内存空间,该内存空间可以立刻被另作他用。

        堆内存主要用于存放对象(在Java中,数组也是对象)。在堆中分配的内存,由JVM的自动垃圾回收器来管理。在堆中产生一个对象后,还可以在栈中定义一个特殊的变量,这个变量的取值等于该对象在堆内存中的首地址,在栈中的这个特殊的变量就是我们常说到的“对象的引用变量”。

3、栈和堆的区别

        Java中栈和堆的区别自然是面试中的常见问题,下面几点就是其具体的区别。

1)各司其职

        最主要的区别就是栈内存是用来存储局部变量和方法调用。而堆内存是用来存储Java中的对象。引用变量指向的对象都存储在堆内存中。

2)独有还是共享

        栈内存归属于单个线程,每个线程都会有一个栈内存,其存储的变量只能在其所属线程中可见,即栈内存可以理解成线程的私有内存。而堆内存中的对象对所有线程可见,堆内存中的对象可以被所有线程访问,是共享的。

3)异常错误

        如果栈内存没有可用的空间用来存储方法调用和局部变量,那么JVM会抛出java.lang.StackOverFlowError。而如果是堆内存没有可用的空间来存储生成的对象,那么JVM会抛出java.lang.OutOfMemoryError。

4)空间大小

        栈内存的存储空间要远远小于堆内存。如果你使用递归的话,那么你的栈很快就会被填满。如果递归没有及时跳出,很可能发生StackOverFlowError异常。你可以通过-Xss选项设置栈内存的大小。-Xms选项可以设置堆的开始时的大小和堆的最大值。


0 0
原创粉丝点击