A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

Heap(堆)  --  Stack(栈)
首先先介绍一下Heap(堆)中分配内存的时间是远大于Stack(栈)中分配的时间的

Stack
每个应用程序运行时,都有属于自己的一段内存空间,用于存放临时变量、参数传递、函数调用时的PC值保存。这叫stack(栈)
stack中的对象或变量只要定义好就可使用了,应用程序结束时会自动释放。
stack中变量的大小和个数会影响exe的文件大小,但速度快。堆中的变量大小与exe大小关系不大,但分配和释放需要耗费的时间远大于stack中分配内存所需的时间。
Heap
所有的应用可以从一个系统共用的空间中申请供自己使用的内存,这个共用的空间叫heap。
而要使用heap中申请的变量或对象只能定义变量指针,并要求在运行过程中通过new来动态分配内存空间,而且必须显示地free你申请过的内存,不过Java的垃圾回收机解决了这个问题,它会帮你释放这部分内存。

每一个线程都会有自己私有的栈空间,随线程创建而创建。
堆是所有线程所共享的,堆中存放所有运行时数据,heap(堆)是再JVM(虚拟机)启动的时候创建的。堆里面存放所有的runtime data ,所有的对象实例和数组等

重要:其实我们平时的赋值都是将一个引用指向了一个对象
java不能成功分配heap的空间,将抛出OutOfMemoryError.
以上摘自http://blog.csdn.net/wl_ldy/article/details/5935528
这里我想用自己理解的方式解释一下为什么String str = “abc”;String str2 = new String(“abc”);
str == str2 为false
这里需要了解一下String str = “abc”;String是一个不可变的类,一旦创建其值是不可改变的。具体是怎么做的,在碰到这个语句的时候后台会自发的创建一个对象来保存这个字符串abc的地址,然后用str这个引用指向后台创建的对象的地址,而我们使用String str2 = new String(“abc”);又自己创建了一个对象,这个对象的地址肯定是唯一的,所以str指向的是系统分配的对象的地址,str2指向的是我们自己创建地址的地址,因此他们两个是不同的。

我们可以从侧面去解释这个问题,如果我们后用new String()创建一个对象,那么这个对象肯定是唯一的,而又在这个话之前进行一次赋值的话,那个时候并没有创建出我们new 出来的对象,所以这时候的str肯定是已经保存了一个地址了的,然后我们又用new创建了一个对象,这个对象相对于堆中的数据肯定会又一个唯一的地址,那么这两个地址一定是不同的。
其实就是 new 出来的地址唯一,那么我们先用String str = “abc”;去创建一个字符串,他又怎么可能会指向我们还没创建的唯一的地址呢?    这样就是一个悖论了!

猜测:
String s = “a”;
猜测:如果String s1 = s+”b”;那么应该是怎样的呢?
代码实现:
String s2 = s+”b”;
String s3 = s+”b”;
s2 == s3  --> false

String s4 = “a” + “b”;
String s5 = “a” + “b”;
String s6 = “ab”;
S4 == s5 --> true
S4 == s6 --> true

所以可以得出结论每次使用String的对象进行字符串的拼接的时候都会返回出一个新的对象,因此我们要避免这种操作,尽量的使用StringBuffer
在StringBuffer的append方法中
public AbstractStringBuilder append(String str) {
        if (str == null) str = "null";
        int len = str.length();
        ensureCapacityInternal(count + len);
        str.getChars(0, len, value, count);
        count += len;
        return this;
}
StringBuffer里面封装着一个char[] value;这样一个对象
每次操作都是在这个创建一个新的数组对象b<假设的名字>,数组长度是value的长度和传入字符串长度的和  --- 通过Array.copy(char[] original,int newLength)这个方法来实现的。然后再通过System.arraycopy()的方法将这String里面的值合并到b里面。

这里String每次拼接都会创建对象,同样的因为String里面封装着一个
final char[] value;他会是一个常量,所以拼接起来的值也会被封装到这个常量里,会多创建出许多常量来。

有不足之处希望多多提点一下。

1 个回复

倒序浏览
我来占层楼啊   
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马