偶然看到一道面试题,Java在实例化一个类的时候,数据在堆和栈中是如何存放的?
  public class A{
  public int i=1;
  public static A a1 = new A();
  public static void mian(String args[]){
  int c = 2;
  A a=new A();
  }
  }
  答案是:
  处于栈中的数据:A对象的引用a和局部变量c
  处于堆中的数据:变量a所指向的对象,变量a1所指向的对象,成员变量i,静态变量a1
  Java的内存机制
  Java把内存分为堆内存和栈内存两个部分
  栈内存:
  在 函数中定义的基本数据类型的变量和对象的引用都存放在栈内存,当在一个函数中定义一个变量时,java在栈中为该变量分配内存空间,当这个变量被用完之后(超过了变量的作用域),java会自动释放掉为该变量分配的内存。因此我们可以这样理解,对于一个局部变量,如果它是一个基本数据类型,那么这个变量存放在栈中;如果这个变量是一个对象,那么该对象存放在堆中,而对象的引用仍然在栈中!
  堆内存:
  堆内存用来存放由 new 创建的对象和数组,所有的成员变量和static修饰的类变量,在堆中分配的内存,由Java虚拟机的自动垃圾回收器来管理。
  当对象的引用在位于栈中时,栈中的这个引用的取值等于数组或对象在堆内存中的首地址,栈中的这个变量成了数组或对象的引用变量,以后可以在程序中使用栈中的引用变量来访问堆中的数组或者对象,引用变量相当于是为数组或者对象起的一个名称。引用变量是普通的变量,定义时在栈中分配,引用变量在程序运行到其作用域之外后被释放。而数组和对象本身在堆中分配,即使程序运行到使用 new 产生数组或者对象的语句所在的代码块之外,数组和对象本身占据的内存不会被释放,数组和对象在没有引用变量指向它的时候,才变为垃圾,不能在被使用,但仍然占据内存空间不放,在随后的一个不确定的时间被垃圾回收器收走(释放掉)。