先了解几个概念

堆heap:对象生存的空间

栈stack:方法调用及变量的生存空间


Java的堆是一个运转时数据区,类的对象从中分配空间。这些对象经过new、newarray、anewarray和 multianewarray等指令建立,它们不需要程序代码来显式的释放。堆是由垃圾回收来负责的,堆的优势是可以静态地分配内存大小,生活期也不用事 先通知编译器,因为它是在运转时静态分配内存的,Java的垃圾搜集器会自动收走这些不再运用的数据。但缺陷是,由于要在运转时静态分配内存,存取速度较慢。

栈的优势是,存取速度比堆要快,仅次于寄存器,栈数据可以共享。但缺陷是,存在栈中的数据大小与生活期必须是确定的,缺乏灵敏性。栈中主要寄存一些基本类 型的变量(,int, short, long, byte, float, double, boolean, char)和对象句柄。

上面说栈中的数据是可以共享的,意思是栈中存储的值是共享的。只有有一个3。

编译器先处置int a = 3;首先它会在栈中创建一个变量为a的引用,然后查找栈中能否有3这个值,如果没找到,就将3寄存出去,然后将a指向3。接着处置int b = 3;在创建完b的引用变量后,因为在栈中已经有3这个值,便将b直接指向3。这样,就出现了a与b同时均指向3的状况。


primitive主数据类型包括int,short,byte,long,double,float,char,boolean。其中String不是主数据类型,String是一个对象。   

对象的引用,也就是句柄,打印出来的话是一串哈希字符串。

对象本省。

所有的局部变量都存在于栈上相对应的堆栈块中。

对象引用变量与 primitive主数据类型变量都放在栈上(这里放在栈上的东西只是数值。上面说的3就是放在栈里的,但是a只是一个指向3的类似指针的东西。引用变量放在栈里的也只是哈希值,然后引用变量指向哈希值)。

不管是实例变量或局部变量。 对象本身都会在堆上。

java的方法,局部变量,方法中的参数,都是存储在栈空间的。


如,new一个Dog对象,Dog d = new Dog();,其中Dog对象是保存在堆空间上的,d也就是Dog对象的引用,保存在栈空间。其中Dog中的变量,假如是对象全局变量,保存的也只是引用。