jvm是基于堆栈的虚拟机,堆和栈都是java中用来存储数据的地方.
(1)堆的特点:
每个java应用进程(一个main线程以及它的子线程)对应一个堆,堆的大小可以通过参数-xms,-xmx来设置。 java中所有通过new出来的对象和数组都存在堆中,可以为各线程共享,堆中的内存空间通过垃圾回收器进行回收。
(2)栈的特点:
栈是线程私有的,栈的生命周期就是线程的生命周期,可以通过-Xss来分配每个线程的栈空间,如果某个线程的栈空间不足,系统会抛*Error异常。栈中是以栈帧为单位进行维护的,java中没调用以方法就会创建一个栈帧,用于存储局部变量区,操作数,等,所以可以说,java中方法的调用过程,其实就是对栈的操作过程(分为压栈和出栈)。基本类型(如short,int...)和对象的引用的保存在栈中,由于这些数据都有已知的固定的大小,栈中的存取速度较快,栈还有一个特点,就是存在栈中的数据可以共享,而堆却不可以,共享的意思就是讲相同的数据可以共用同一内存块, 比如 :
int a=1;
int b=1;
上面过程建立了a和b两个引用,当执行b=1的时候,会先去栈中找是否存在1的值,如果存在,就不会开辟新的内存块给1了,而是直接使用之前的内存,把它的地址直接赋给b,所以a引用和b引用指向相同的内存地址,这也就不难解释a==b的道理了。
还有String的情况, 比如:
String c = "aaa";
String d = "aaa";
这里的c==d也是为true,也可用上面的原理来解释,就是说当以上面的方式来创建字符串的时候,jvm会将创建的字符串保存在栈中,并拥有的栈*享的特点,所以c==d,但是通过new String("aaa")的方式的话就比较麻烦了,首先会在栈中寻找或者创建(不可能之间建过,就可公用)一个"aaa",然后用它来在堆中又新建(肯定开辟新的空间)一个字符串。