java堆栈存储对比

一、堆、栈主要关系
1. 栈
函数中定义的基本类型(int,double,float,char,short,float,boolean,byte)和引用变量都在栈中分配,引用变量就相当于是为数组或对象起的一个名称,比如String str = new String("abc")中str就是一个引用变量。以后就可以在程序中使用栈中的引用变量来访问堆中的数组或对象。
比如int a=3的创建过程是在栈中先创建一个变量为a指向int的引用,然后查找栈中是否有3这个值,没有就将3存放进栈,然后将a指向3。
栈中数据可以共享:

int a = 3;
int b = 3; 

编译器首先处理int a=3;在栈中创建变量为a的引用,找是否有面值为3的地址,没有就开辟一个地址存放3,饭后将a指向3的地址。接着是处理int b=3;在创建完b的引用后,由于栈中以及有3这个字面值,就直接把b指向原来3的地址。所以就有a,b两个变量共享3的情况。
2. 堆
其实从上面也可以看出,除去基本类型与String str1 = "abc"这样的方式,如String str = new String("abc")中str是一个引用变量对象的创建(在栈中),使用new()构造出来的对象都是在堆中存储。无论里面的值是不是一样,都会开辟一个新的空间,即动态的分配地址空间(即并不是编译的时候分配,程序运行到这里的时候再分配,所以数组对象这种就很占内存)。
为什么说String有点特殊呢?
例如:

    String str1 = "abc";
    String str2 = "abc";
    System.out.println(str1==str2);

这里为什么会是true呢?这里用String定义的常量实际上和int a=3的创建方法是一样的,上面的代码说明str1和str2是指向栈中同一个对象的。
例如:

    String str1 = new String("abc");
    String str2 = new String("abc");
    System.out.println(str1==str2);//false

上面的例子我没有骗你,你可以敲来试试,其实这个时候就和堆有关系了,之前不是说String其实是封装类型吗?也就是说它其实是一个对象,那么Java中对象是通过new()来创建的,也就是说这里的两个abc都是存放在堆中,并且引用变量str1,str2指向的地址还不一样,所以返回false。如果你用System.out.println(str1.equals(str2));来比较结果就是true(当变量是引用类型时,相当于比较的它们的值)
这里有一个例子

        String str1 = "ja";
        String str2 = "va";
        String str3 = "java";
        String str4 = str1+str2;
        System.out.println(str4);
        System.out.println(str3.equals(str4));//true
        System.out.println(str3==str4);//false

WTF?好像你觉得str3和str4应该是同样的创建方法,都在栈当中是吧。其实一开始我也是觉得,后来自己敲出来之后才发现原来如此啊。打印false的原因是,java 重载了“+”,网上查询发现“+”其实是调用了StringBuilder对象里面的append方法,所以使用了“+”其实是在堆中生成了一个新的对象str4(总共有3个对象哦,第一个对象"ja",第二个对象"va",第三个"java"),即现在的str4实际上已经是堆中的数据了。所以(s3 == s4)打印false

二、堆栈各自的优缺点
栈的优缺点:存取速度快,仅次于CPU中的寄存器,并且数据可以共享。缺点是栈中的数据大小必须确定,缺乏灵活性。
堆的优缺点:优势是可以动态的分配内存大小,生存期也不必事先告诉编译器Java的垃圾收集器会自动收走这些不再使用的数据。因为要动态分配内存,所以运行时就会消耗更多的时间和空间
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值