读书人

Java进--有於Java中堆的思考

发布时间: 2012-11-10 10:48:50 作者: rapoo

Java入--有於Java中堆的思考

Java入--有於Java中堆的思考

1. (stack)堆(heap)都是Java用在Ram中存放的地方。C++不同,Java自管理和堆,程式不能直接地置或堆。

2. 的是,存取速度比堆要快,次於直接位於CPU中的寄存器。但缺是,存在中的大小生存期必是定的,缺乏活性。另外,可以共用,第3。堆的是可以地分配大小,生存期也不必事先告器,Java的垃圾收集器自收走些不再使用的。但缺是,由於要在行分配,存取速度慢。
?
3. Java中的型有。
?
一是基本型(primitive types), 共有8,即int, short, long, byte, float, double, boolean, char(注意,有string的基本型)。型的定是通如int a = 3; long b = 255L;的形式定的,自。值得注意的是,自存的是字面值,不是的例,即不是的引用,有的存在。如int a = 3; 的a是一指向int型的引用,指向3字面值。些字面值的,由於大小可知,生存期可知(些字面值固定定在某程式面,程式退出後,字段值就消失了),出於追求速度的原因,就存在於中。
?
另外,有一很重要的特殊性,就是存在中的可以共用。假我同定:
?
int a = 3;
int b = 3;

器先理int a = 3;首先它在中建一a的引用,然後搜有有字面值3的地址,找到,就一存放3字面值的地址,然後a指向3的地址。接著理int b = 3;在建完b的引用後,由於在中已有3字面值,便b直接指向3的地址。,就出了ab同均指向3的情。
?
特注意的是,字面值的引用象的引用不同。假定象的引用同指向一象,如果一象引用修改了象的部,那另一象引用也即刻反映出化。相反,通字面值的引用修改其值,不致另一指向此字面值的引用的值也跟著改的情。如上例,我定完ab的值後,再令a=4;那,b不等於4,是等於3。在器部,遇到a=4;,它就重新搜索中是否有4的字面值,如果有,重新地址存放4的值;如果已有了,直接a指向地址。因此a值的改不影到b的值。
?
另一是包,如Integer, String, Double等相的基本型包起的。些全部存在於堆中,Java用new()句示地告器,在行才根需要建,因此比活,但缺是要用更多的。 4. String是一特殊的包。即可以用String str = new String("abc");的形式建,也可以用String str = "abc";的形式建(作比,在JDK 5.0之前,你未Integer i = 3;的算式,因字面值是不能通用的,除了String。而在JDK 5.0中,算式是可以的!因器在後行Integer i = new Integer(3)的)。前者是的的建程,即在Java中,一切都是象,而像是的例,全部通new()的形式建。Java中的有些,如DateFormat,可以通的getInstance()方法返回一新建的,似乎反了此原。其不然。用了例模式返回的例,只不例是在部通new()建的,而getInstance()向外部藏了此。那什在String str = "abc";中,有通new()建例,是不是反了上述原?其有。
?
5. 於String str = "abc"的部工作。Java部此句化以下步:
?
(1)先定一名str的String的象引用:String str;
?
(2)在中搜有有存放值"abc"的地址,如果有,一存放字面值"abc"的地址,接著建一新的String的象o,o的字符串值指向地址,而且在中地址旁下引用的象o。如果已有了值"abc"的地址,搜象o,返回o的地址。
?
(3)str指向象o的地址。
?
值得注意的是,一般String中字符串值都是直接存值的。但像String str = "abc";合下,其字符串值是保存了一指向存在中的引用!
?
了更好地明,我可以通以下的代行。
?
String str1 = "abc";
?String str2 = "abc";
?System.out.println(str1==str2); //true

注意,我不用str1.equals(str2);的方式,因比字符串的值是否相等。==,根JDK的明,只有在引用都指向了同一象才返回真值。而我在要看的是,str1str2是否都指向了同一象。
?果明,JVM建了引用str1和str2,但只建了一象,而且引用都指向了象。
?
我再更一步,以上代改成:
?
String str1 = "abc";
?String str2 = "abc";
?str1 = "bcd";
?System.out.println(str1 + "," + str2); //bcd, abc
?System.out.println(str1==str2); //false

就是,值的化致了象引用的化,str1指向了另外一新象!而str2仍指向原的象。上例中,我str1的值改"bcd",JVM在中有存放值的地址,便了地址,建了一新的象,其字符串的值指向地址。
?
事上,String被成不可改(immutable)的。如果你要改其值,可以,但JVM在行根新值悄悄建了一新象,然後象的地址返回原的引用。建程是完全自行的,但它竟用了更多的。在要求比敏感的境中,有一定的不良影。
?
再修改原代:
?
String str1 = "abc";
?String str2 = "abc";
?
str1 = "bcd";
?
String str3 = str1;
?System.out.println(str3); //bcd
?
String str4 = "bcd";
?System.out.println(str1 == str4); //true

str3象的引用直接指向str1所指向的象(注意,str3有建新象)。str1改完其值後,再建一String的引用str4,指向因str1修改值而建的新的象。可以,回str4也有建新的象,而再次中的共用。
?
我再接著看以下的代。
?
String str1 = new String("abc");
?String str2 = "abc";
?System.out.println(str1==str2); //false

建了引用。建了象。引用分指向不同的象。
?
String str1 = "abc";
?String str2 = new String("abc");
?System.out.println(str1==str2); //false

建了引用。建了象。引用分指向不同的象。
?
以上段代明,只要是用new()新建象的,都在堆中建,而且其字符串是存值的,即使中的相同,也不中的共用。
?
6. 型包的值不可修改。不是String的值不可修改,所有的型包都不能更改其部的值。 7. 建:
?
(1)我在使用如String str = "abc";的格式定,是想然地,我建了String的象str。心陷阱!象可能有被建!唯一可以肯定的是,指向String的引用被建了。至於引用到底是否指向了一新的象,必根上下文考,除非你通new()方法要地建一新的象。因此,更的法是,我建了一指向String的象的引用str,象引用指向了某值"abc"的String。清醒地到一排除程式中以的bug是很有助的。
?
(2)使用String str = "abc";的方式,可以在一定程度上提高程式的行速度,因JVM自根中的情定是否有必要建新象。而於String str = new String("abc");的代,一概在堆中建新象,而不管其字符串值是否相等,是否有必要建新象,而加重了程式的。思想是享元模式的思想,但JDK的部在是否用了模式,不得而知。
?
(3)比包面的值是否相等,用equals()方法;包的引用是否指向同一象,用==。
?
(4)由於String的immutable性,String需要常其值,考使用StringBuffer,以提高程式效率。

?

读书人网 >编程

热点推荐