栈与堆,String和StringBuffer(一)

        最近读了一篇文章 -- 《提高String和StringBuffer性能的技巧》, 感觉不错,绝定记录一下顺便写点感受,既然是性能,一般都是内存方面的考虑,说到内存得先说说java中的栈与堆。

        java在内存中用来存放数据的分为栈(stack)和堆(heap),java自行管理,栈内存的特点是存取速度快,仅次于直接位于CPU中的寄存器,但栈中的数据大小与生存期必须是确定的,缺乏灵活性。而堆可以动态地分配内存大小,生命存期也不必事先声明,但正因为它动态分配内存的特性会使得存取速度慢。

        java中所有数据都是存放在栈与堆中,java基本数据类型共有8种,定义方式: int  a = 3; 这里a称为自动变量,自动变量里存放的是字面值,也就是说这里3是字面值,a指向3,字面值数据是大小可知,生命周期可知,所以它是存放在栈内存中的。

        栈中还有个特性就是数据共享,在栈中所有的数据都可被共享。int  a  = 3; int  b = 3; 这句代码会首先在栈中创建一个变量a,然后会先在栈内存中查找为3的字面值, 若找到 便将a指向它,若未找到 则开辟一个内存区存放3,再将a指向它。所以这两句代码执行完后,会在栈内存中创建两个变量a和b,但只创建一个为3的字面值,a和b都指向它。

         java还有一种类型 -- 类类型,就拿int对应的封装类(Integer)来说,类类型使用前必须实例化,一般通过new()来显示的创建,准确的说类对象的创建是在运行时根据需要来动态创建的,特性是比较灵活,但要占用更多的时间,至于什么是运行时,在后面会有个介绍。在JDK 5.0中及以后的版本,都可以这样Integer i = 3; 因为在后台编译器会转换成Integer  i = new Integer(3);

         值得一提的是:

         int  a  = 3;    int  b   =3 ;

         Integer  i  = new Integer(3);    Integer j  = new Integer(3);

        这两种的差别,刚才说了第一行的代码会在栈中创建两个变量a和b,创建一个字面值3,a和b指向3,下一行的代码会在栈中创建两个对象引用i和j,同时会在堆中创建两个对象(虽然),i和j分别指向这两个对象,可见堆内存中数据不是共享的。

        若是把Integer  i  = new Integer(3);    Integer j  = new Integer(3); 换成Integer i = new Integer(3); Integer j = i;  这种情况则是在栈中创建两个对象引用,在堆中创建一个对象new Integer(3),i和j同时指向这个对象,这种多个引用同时指向同一个内存地址的情况和上面的java基本类型的情况咋一看是相同的,但其实不然,看下面代码

        int  a = 3;  int  b  = 3;    这时a和b指向的是同一个3,若此时将a  = 4; b是不会改变值,将a的值改变成4,会在栈内存中重新查找字面值为4的地址,找到后将a指向4,若为找到则开辟一个内存区来存放4,所以刚开始a和b同时指向一个字面值,它与类类型不同,其中一个变量改变另一个不受影响。

        而类类型则不同,Integer这个类型不太好说明,比如说有个学生类class  Student,

       Student  s1 = new Student();

       Student  s2 =  s1 ;  这里s1和s2是指向同一个对象,可以说是同一个学生,若改变这个学生的任何一个属性,s1和s2都会发生改变。这就是类类型与基本类型不同的地方。

        String这个类型比较特殊,因为它可以通过String str = new String("abc"); 和 String str = "abc"; 两种方式来创建,String str = new String("abc"); 这句与上面说的类类型的是一样,而这句String str = "abc"; 则与基本类型是一样的,这里的"abc"会存放在栈中的唯一字符串池,所以从性能上说后者优于前者。

        在堆内存中也可以实现类似栈中的这种数据共享,String.intern() 这个方法的使用,

String str = new String("abc"); 这样一句话是在堆中创建一个"abc"的对象,它根本不用去管堆中是否有已经叫"abc"的对象,  若在后面加上一句String.intern();  则会先检查字符串对象是否存在,若存在则将引用指向它,不存在时才创建,有点像基本类型,那么下面那种的性能如何呢?

        String  str  =  "abc";    //栈中的读取速度最快,性能最佳

        String  str  = new Stirng("abc");  str = str.intern();    //检查了对象是否存在,避免了创建相同值的重复对象,但毕竟还在堆中操作,性能其次。

        String  str  = new String("abc");   //不多说了, 性能最次。

        先写到这。。。。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值