月亮的太陽

          小乖的BLOG
          posts - 114, comments - 41, trackbacks - 0, articles - 27
            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理
          對(duì)象創(chuàng)建

          對(duì)象的創(chuàng)建是一個(gè)非常昂貴的工作,而由于對(duì)象的創(chuàng)建而導(dǎo)致經(jīng)常性的垃圾收集則是一個(gè)更加消耗時(shí)間和CPU的操作。我們?cè)诰幋a時(shí),應(yīng)當(dāng)盡量的減少對(duì)象的創(chuàng)建。不要在經(jīng)常被執(zhí)行的代碼中創(chuàng)建對(duì)象;使用集合對(duì)象時(shí)最好預(yù)先分配其大小;當(dāng)一個(gè)class的多個(gè)實(shí)例都需要獲取某個(gè)對(duì)象時(shí),最好能標(biāo)記那個(gè)對(duì)象static;當(dāng)不需要stack trace時(shí)盡可能的重用異常實(shí)例等等都能很有效的避免對(duì)象創(chuàng)建而導(dǎo)致的額外的開銷。下面是一些常用的有效的策略:

          1)      對(duì)象池技術(shù)

          Java中開發(fā)一個(gè)普遍性的對(duì)象池架構(gòu)可以更好地利用資源,并可以使對(duì)象創(chuàng)建的成本降到最小。大多數(shù)人對(duì)直接或間接運(yùn)用對(duì)象池來連接一個(gè)數(shù)據(jù)庫都很熟悉。但通常你也可以將對(duì)象放入對(duì)象池中從而節(jié)省重要的資源、提高程序的效率并控制對(duì)不充足資源的訪問。出于對(duì)設(shè)計(jì)、成本或性能的考慮,放入對(duì)象池中的對(duì)象通常是有限的。它們或者是初始化成本很高的對(duì)象,或者是很少用的對(duì)象。運(yùn)用對(duì)象池我們可以管理競(jìng)爭(zhēng)性客戶端對(duì)有限的對(duì)象集的訪問。

          對(duì)象池主要是可以更好地運(yùn)用你的資源。例如,設(shè)想有相當(dāng)多的客戶要有效運(yùn)用很少的數(shù)據(jù)庫連接或網(wǎng)絡(luò)連接。通過限制對(duì)對(duì)象的訪問(只在客戶端需要的時(shí)候才能訪問對(duì)象),你就可以釋放資源,讓其它客戶端使用。通過對(duì)象池提高對(duì)象的利用率通常可以提高系統(tǒng)的性能。

          你可以使用對(duì)象池使初始化的成本達(dá)到最小。典型的例子包括數(shù)據(jù)庫、網(wǎng)絡(luò)連接和線程。這樣的連接通常需要很多時(shí)間來初始化。一旦創(chuàng)建了這些連接,你就可以重用它們,從而極大地節(jié)省了成本。因此,你可以將初始化成本很高(從時(shí)間、內(nèi)存或其它資源方面考慮)的對(duì)象放入對(duì)象池中。例如,大多數(shù)容器都將EJB放入對(duì)象池中,從而避免重復(fù)的資源分配和狀態(tài)初始化。

          一個(gè)設(shè)計(jì)良好的對(duì)象池架構(gòu)具有普遍性,它適合不同應(yīng)用程序的需要。可以讓你控制對(duì)象池的容量、對(duì)象填充策略和對(duì)象狀態(tài)。它可以極大地提高你的應(yīng)用程序的效率,不管從速度方面考慮,還是從資源利用率方面考慮,該架構(gòu)都可以提供這樣的好處。

          在這里,給大家推薦一個(gè)開源的項(xiàng)目Commons-Poolhttp://jakarta.apache.org/commons/pool/),我還沒來得及研究,誰用過了,感覺好的,麻煩告訴我一下,謝謝!

          2)      ThreadLocal技術(shù)

          使用此技術(shù)獲取線程綁定的帶狀態(tài)的單例對(duì)象。

          3)      單例模式

          通過單例模式或使定義對(duì)象static來使得對(duì)象的實(shí)例只能有一個(gè)并被其他對(duì)象所共享。

          4)      枚舉常量

          使用整數(shù)取代字符串作為枚舉常量,比如FEMALEMALE我們可以用整數(shù)12來替代。這樣將帶來速度上和內(nèi)存上的優(yōu)勢(shì)。

          5)      使用SoftReferenceWeakReferencePhantomReference引用類

          引用類的主要功能就是能夠引用仍可以被垃圾收集器回收的對(duì)象。在引入引用類之前,我們只能使用強(qiáng)引用(Strong Reference)。例如obj這個(gè)引用將引用堆中存儲(chǔ)的一個(gè)對(duì)象,只要obj引用還存在,垃圾收集器就永遠(yuǎn)不會(huì)釋放用來容納該對(duì)象的存儲(chǔ)空間。當(dāng)obj超出范圍或被顯式指定為null時(shí),垃圾收集器就認(rèn)為沒有對(duì)這個(gè)對(duì)象的其他引用,也就可以收集它了。然而還需要注意一個(gè)重要的細(xì)節(jié):僅憑對(duì)象可以被收集并不意味著垃圾收集器的一次指定運(yùn)行就能夠回收它。由于各種垃圾收集算法不同,某些算法會(huì)更頻繁地分析生存期較短的對(duì)象,而不是較老、生存期較長的對(duì)象。因此,一個(gè)可供收集的對(duì)象可能永遠(yuǎn)也不會(huì)被回收。如果程序在垃圾收集器釋放對(duì)象之前結(jié)束,這種情況就可能會(huì)出現(xiàn)。因此,概括地說,你永遠(yuǎn)無法保證可供收集的對(duì)象總是會(huì)被垃圾收集器收集。

          讓我們來看看一些術(shù)語和定義:

          強(qiáng)可及對(duì)象(Strongly Reachable):可以通過強(qiáng)引用訪問的對(duì)象。

          軟可及對(duì)象(Softly Reachable):不是強(qiáng)可及對(duì)象,并且能夠通過軟引用訪問的對(duì)象。

          弱可及對(duì)象(Weakly Reachable):不是強(qiáng)可及對(duì)象也不是軟可及對(duì)象,并且能夠通過弱引用訪問的對(duì)象。

          虛可及對(duì)象(Phantomly Reachable):不是強(qiáng)可及對(duì)象、軟可及對(duì)象,也不是弱可及對(duì)象,已經(jīng)結(jié)束的,可以通過虛引用訪問的對(duì)象。

          清除:將引用對(duì)象的refernce域設(shè)置為null,并將引用類在堆中引用的對(duì)象聲明為可結(jié)束的。

          SoftReference類:SoftReference類的一個(gè)典型用途就是用于內(nèi)存敏感的高速緩存。SoftReference的原理是:在保持對(duì)對(duì)象的引用時(shí)保證在JVM報(bào)告內(nèi)存不足情況之前清楚所有的軟引用。關(guān)鍵之處在于,垃圾收集器在運(yùn)行時(shí)可能會(huì)(也可能不會(huì))釋放軟可及對(duì)象。對(duì)象是否被是否取決于垃圾收集器的算法以及垃圾收集器運(yùn)行時(shí)可用的內(nèi)存數(shù)量。

          WeakReference類:WeakReference類的一個(gè)典型用途就是規(guī)范化映射(Canonicalized Mapping)。另外,對(duì)于那些生存期相對(duì)較長而且重新創(chuàng)建的開銷也不高的對(duì)象來說,弱引用也比較有用。關(guān)鍵之處在于,垃圾收集器運(yùn)行時(shí)如果碰到了弱可及對(duì)象,將釋放 WeakReference 引用的對(duì)象。然而,請(qǐng)注意,垃圾收集器可能要運(yùn)行多次才能找到并釋放弱可及對(duì)象。

          PhantomReference類:PhantomReference 類只能用于跟蹤對(duì)被引用對(duì)象即將進(jìn)行的收集。同樣,它還能用于執(zhí)行 pre-mortem 清除操作。 PhantomReference 必須與 ReferenceQueue 類一起使用。需要 ReferenceQueue 是因?yàn)樗軌虺洚?dāng)通知機(jī)制。當(dāng)垃圾收集器確定了某個(gè)對(duì)象是虛可及對(duì)象時(shí), PhantomReference 對(duì)象就被放在它的 ReferenceQueue 上。將 PhantomReference 對(duì)象放在 ReferenceQueue 上也就是一個(gè)通知,表明 PhantomReference 對(duì)象引用的對(duì)象已經(jīng)結(jié)束,可供收集了。這使您能夠剛好在對(duì)象占用的內(nèi)存被回收之前采取行動(dòng)。

          在某些場(chǎng)合引用類還是很有用的,具體可以參考文章Java2引用類使用指南(http://www-128.ibm.com/developerworks/cn/java/j-refs/index.html)。

          6)      盡可能少的減少不必要對(duì)象的生成

          盡可能減少在循環(huán)中創(chuàng)建對(duì)象,使用StringBuffer而不要使用String來做連接操作等等。

          7)      改變對(duì)象的創(chuàng)建時(shí)機(jī)

          通過提前創(chuàng)建對(duì)象或延遲到使用時(shí)再創(chuàng)建對(duì)象,來做到性能優(yōu)化和避免創(chuàng)建過多的對(duì)象。

          Tracker:http://www.aygfsteel.com/patrick/archive/2005/12/25/25348.aspx

          主站蜘蛛池模板: 日喀则市| 虎林市| 西林县| 西乌珠穆沁旗| 清水河县| 邹城市| 安岳县| 城市| 东安县| 监利县| 辰溪县| 闽清县| 乌海市| 合水县| 樟树市| 前郭尔| 周口市| 阿拉尔市| 九龙坡区| 诏安县| 施甸县| 巍山| 方山县| 佛山市| 丽江市| 青河县| 体育| 青浦区| 霍林郭勒市| 莎车县| 工布江达县| 化隆| 望都县| 柏乡县| 衡水市| 阿图什市| 萨嘎县| 福安市| 奉贤区| 乌什县| 长汀县|