栈和堆
栈内存和堆内存
栈和堆都是Java用来在Ram中存放数据的地方。与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈和堆。
栈
在函数中定义的一些基本类型的变量和对象的引用都是在函数的栈内存中分配。当定义一个变量是,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为该变量分配的内存空间,该内存空间可以立刻被另作他用。栈先进后出,队列先进先出。
栈的优势是,存取速度比堆快,仅次于直接位于CPU中的寄存器,缺点是,存在栈中的数据大小与生存周期必须是确定的,缺乏灵活性。另外栈数据可以共享。
堆
堆内存用于存放由new创建的对象和数组。在堆分配的内存,由java虚拟机自动垃圾回收器来管理。在数组和对象在没有引用变量指向它的时候,才变成垃圾,不能再次被使用,但是仍占着内存,在随后的一个不确定的时间被垃圾回收器释放掉。这也是java比较占内存的主要原因。
堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,Java的垃圾收集器会自动收走这些不再使用的数据。缺点是要在运行时动态分配内存,存取速度较慢。
http://blog.csdn.net/songjie521/article/details/3368386
当一个方法执行时,每个方法都会建立自己的内存栈,在这个方法中定义的变量将会逐个放入这块栈内存里,随着方法的执行结束,这个方法的内存栈也将自然销毁。因此,所有在方法中定义的局部变量都是放在栈内存中的;
在程序中创建一个对象时,这个对象将被保存到运行时数据区中,以便反复利用(对象创建成本较大),这个运行时数据区就是堆内存。堆内存中的对象不会随方法的结束而销毁,及时方法结束后,这个对象还可能被另一个引用变量所引用,则这个对象依然不会被销毁,只有当一个对象没有任何引用变量引用它时,系统的垃圾回收器才会在合适的时候回收它。
方法区
方法区域存放了所加载的类的信息(名称、修饰符等)、类中的静态变量、类中定义为final类型的常量、类中的Field信息、类中的方法信息,当开发人员在程序中通过Class对象中的getName、isInterface等方法来获取信息时,这些数据都来源于方法区域,同时方法区域也是线程共享的。
区别:
http://droidyue.com/blog/2014/12/07/differences-between-stack-and-heap-in-java/
堆和栈都是内存中的一部分,有着不同的作用,而且一个程序需要在这片区域上分配内存。众所周知,所有的Java程序都运行在JVM虚拟机内部,我们这里介绍的自然是JVM(虚拟)内存中的堆和栈。
①栈内存用来存储局部变量和方法调用。而堆内存用来存储Java中的对象。无论是成员变量,局部变量,还是类变量,它们指向的对象都存储在堆内存中。
②栈内存归属于单个线程,每个线程都会有一个栈内存,其存储的变量只能在其所属线程中可见,即栈内存可以理解成线程的私有内存。而堆内存中的对象对所有线程可见。堆内存中的对象可以被所有线程访问。
③栈内存没有可用的空间存储方法调用和局部变量,JVM会抛出java.lang.StackOverFlowError。而如果是堆内存没有可用的空间存储生成的对象,JVM会抛出java.lang.OutOfMemoryError。
④栈的内存要远远小于堆内存,如果你使用递归的话,那么你的栈很快就会充满。如果递归没有及时跳出,很可能发生StackOverFlowError问题。可以通过-Xss选项设置栈内存的大小。-Xms选项可以设置堆的开始时的大小,-Xmx选项可以设置堆的最大值。