Vector 總結
Vector是在java編程中比較常用的動態數組。一直以為它是個數組的鏈表,當內存不夠用了,就新申請一個capacityIncrement大小的數組,連到原來的鏈表上。
在仔細閱讀源代碼后發現,Vector并沒有任何鏈表的性質。它是一個純粹的數組。當內存不夠用時,就重新初始化一個容量較大新數組,然后使用System.arraycopy()函數將原有的數組copy到新的數組當中。
System.arraycopy()是一個由系統平臺來實現的函數,這樣的系統調用性能是比較高的。
即使如此,我們在寫程序時,注意initialCapacity(初始容量)和capacityIncrement(增量)的設置,將會有效的減少重新定義數組并且拷貝數組的次數。
例如:
Image img = Image.createImage(”/xxx.png”);
Image img2 = img;
這張圖片非常大,在使用完img之后,我釋放掉它,然后重新申請另一個圖片。于是,內存爆了。因為img2仍然持有xxx.png的引用,所以無法釋放。
Vectro中存儲的也是引用,所以在使用時應該更加注意編程規范,以免發生類似的問題。其實應該盡量避免使用多個引用。
上面說了這些題外話,正是想警告各位程序員,Vector是一個可變的Object數組,一個引用數組。所以請大家使用時要小心,別想當然的以為它是一個容器,它里面存儲的可不是對象,而是引用。
而且,在釋放曾經加入到vector的對象時,對象本身并不會被真正釋放,得到回收。只是原有的引用無法再使用罷了。
最后還有一點技巧。
應該盡量使用索引獲取對象,避免使用IndexOf()方法。把它當做堆棧來使用時更應該注意,要避免使用insertElementAt()方法。
此外,j2me中的Stack類是基于Vector實現的,使用時也要留心。
在仔細閱讀源代碼后發現,Vector并沒有任何鏈表的性質。它是一個純粹的數組。當內存不夠用時,就重新初始化一個容量較大新數組,然后使用System.arraycopy()函數將原有的數組copy到新的數組當中。
System.arraycopy()是一個由系統平臺來實現的函數,這樣的系統調用性能是比較高的。
即使如此,我們在寫程序時,注意initialCapacity(初始容量)和capacityIncrement(增量)的設置,將會有效的減少重新定義數組并且拷貝數組的次數。
例如:
Vector v = new Vector(10, 10);//初始容量為10,增量10
Integer[] ints = new Integer11;
for (int i = 0; i < ints.length; i++) {
ints = new Integer(i);
v.addElement(ints);
}
Integer[] ints = new Integer11;
for (int i = 0; i < ints.length; i++) {
ints = new Integer(i);
v.addElement(ints);
}
在這里,當v添加第11個Integer的時候,v就會自動創建一個長度為20的數組(當前容量+增量),以后每次裝滿數組,都會重新按增量追加數組長度。
所以,設置一個合適的初始容量和增量,將會提高Vector的效率。千萬別像我一樣,把它當做鏈表。因為鏈表在增長空間時是不會影響到以前使用的空間和數據的。
我想指出一點,因為Vector中存儲的,實際上都是Object變量,大家可以把它理解為指針。重新初始化Vector內置的數組并且拷貝,相當于對一個指針數組進行操作,并不等同于對輸入類型的重新分配內存。
就是說Vector的重新分配,不論進行多少次都不涉及到Integer對象的創建,拷貝等工作。它只是重新創建并拷貝“指針”數組,也就是Object數組。
此外,java中有一個容易被忽視的基本概念。當某個對象再沒有指向該對象的引用時,垃圾回收器才會自動將其自動釋放。不小心使用,很容易給程序造成內存問題。
例如:
Vector v = new Vector(10, 10);//初始容量為10,增量10
Integer[] ints = new Integer11;
for (int i = 0; i < ints.length; i++) {
ints = new Integer(i);
v.addElement(ints);
}
ints = null;//對它的釋放將造成數組元素的釋放。但是由于v中還保存有元素的引用,所以這些Integer對象并不會被回收。
我強調這個問題,是因為曾經寫過一段代碼:Integer[] ints = new Integer11;
for (int i = 0; i < ints.length; i++) {
ints = new Integer(i);
v.addElement(ints);
}
ints = null;//對它的釋放將造成數組元素的釋放。但是由于v中還保存有元素的引用,所以這些Integer對象并不會被回收。
Image img = Image.createImage(”/xxx.png”);
Image img2 = img;
這張圖片非常大,在使用完img之后,我釋放掉它,然后重新申請另一個圖片。于是,內存爆了。因為img2仍然持有xxx.png的引用,所以無法釋放。
Vectro中存儲的也是引用,所以在使用時應該更加注意編程規范,以免發生類似的問題。其實應該盡量避免使用多個引用。
上面說了這些題外話,正是想警告各位程序員,Vector是一個可變的Object數組,一個引用數組。所以請大家使用時要小心,別想當然的以為它是一個容器,它里面存儲的可不是對象,而是引用。
而且,在釋放曾經加入到vector的對象時,對象本身并不會被真正釋放,得到回收。只是原有的引用無法再使用罷了。
最后還有一點技巧。
應該盡量使用索引獲取對象,避免使用IndexOf()方法。把它當做堆棧來使用時更應該注意,要避免使用insertElementAt()方法。
此外,j2me中的Stack類是基于Vector實現的,使用時也要留心。
posted on 2008-08-15 15:19 LukeW 閱讀(192) 評論(0) 編輯 收藏 所屬分類: Tips, Tricks, Hints & Code