一、栈
  栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器,当超过变量的作用域后,java会自动释放掉为该变量分配的内存空间,该内存空间可以立刻被另作他用。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。栈数据可以共享。
  那些数据存放在栈中?
  基本数据类型(int, short, long, byte, float, double, boolean, char)的变量存放于栈中。
  对象的引用存放于栈中。
  栈数据共享具体指什么意思?
  int a = 3; int b = 3;
  编译器先处理int a = 3;首先它会在栈中创建一个变量为a的引用,然后查找有没有字面值为3的地址,没找到,开辟一个存放3这个字面值的地址,然后将a指向3的地址。接着处理int b = 3;在创建完b的引用变量后,由于在栈中已经有3这个字面值,便将b直接指向3的地址。这样,出现了a与b同时均指向3的情况。即共享了3这个栈数据。
  另外,比较特殊的是String,虽然String类型不是简单的基本数据类型,但是当用String a="abc"这样的语法定义String变量的时候,会把数据存储在栈中,因此也会有上面所说的数据共享特性。
  二、堆
  堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器。堆数据在没有引用变量指向它的时候,才变成垃圾,不能再被使用,但是仍然占着内存,在随后的一个不确定的时间被垃圾回收器释放掉。但缺点是,由于要在运行时动态分配内存,存取速度较慢。
  那些数据存放在堆中?
  堆内存用于存放由new创建的对象和数组,即堆主要是用来存储对象的。Java中所有对象的存储空间都是在堆中分配的,但是这个对象的引用却是在堆栈中分配,也是说在建立一个对象时从两个地方都分配内存,在堆中分配的内存实际建立这个对象,而在堆栈中分配的内存只是一个指向这个堆对象的指针(引用)而已。