<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    編程生活

       :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      113 隨筆 :: 0 文章 :: 18 評(píng)論 :: 0 Trackbacks
    并非本人原創(chuàng).
    1.垃圾收集算法的核心思想

    Java語(yǔ)言建立了垃圾收集機(jī)制,用以跟蹤正在使用的對(duì)象和發(fā)現(xiàn)并回收不再使用(引用)的對(duì)象。該機(jī)制可以有效防范動(dòng)態(tài)內(nèi)存分配中可能發(fā)生的兩個(gè)危險(xiǎn):因內(nèi)存垃圾過(guò)多而引發(fā)的內(nèi)存耗盡,以及不恰當(dāng)?shù)膬?nèi)存釋放所造成的內(nèi)存非法引用。

    垃圾收集算法的核心思想是:對(duì)虛擬機(jī)可用內(nèi)存空間,即堆空間中的對(duì)象進(jìn)行識(shí)別,如果對(duì)象正在被引用,那么稱(chēng)其為存活對(duì)象,反之,如果對(duì)象不再被引用,則為垃圾對(duì)象,可以回收其占據(jù)的空間,用于再分配。垃圾收集算法的選擇和垃圾收集系統(tǒng)參數(shù)的合理調(diào)節(jié)直接影響著系統(tǒng)性能,因此需要開(kāi)發(fā)人員做比較深入的了解。

    2.觸發(fā)主GC(Garbage Collector)的條件

    JVM進(jìn)行次GC的頻率很高,但因?yàn)檫@種GC占用時(shí)間極短,所以對(duì)系統(tǒng)產(chǎn)生的影響不大。更值得關(guān)注的是主GC的觸發(fā)條件,因?yàn)樗鼘?duì)系統(tǒng)影響很明顯。總的來(lái)說(shuō),有兩個(gè)條件會(huì)觸發(fā)主GC:

    ①當(dāng)應(yīng)用程序空閑時(shí),即沒(méi)有應(yīng)用線(xiàn)程在運(yùn)行時(shí),GC會(huì)被調(diào)用。因?yàn)镚C在優(yōu)先級(jí)最低的線(xiàn)程中進(jìn)行,所以當(dāng)應(yīng)用忙時(shí),GC線(xiàn)程就不會(huì)被調(diào)用,但以下條件除外。

    ②Java堆內(nèi)存不足時(shí),GC會(huì)被調(diào)用。當(dāng)應(yīng)用線(xiàn)程在運(yùn)行,并在運(yùn)行過(guò)程中創(chuàng)建新對(duì)象,若這時(shí)內(nèi)存空間不足,JVM就會(huì)強(qiáng)制地調(diào)用GC線(xiàn)程,以便回收內(nèi)存用于新的分配。若GC一次之后仍不能滿(mǎn)足內(nèi)存分配的要求,JVM會(huì)再進(jìn)行兩次GC作進(jìn)一步的嘗試,若仍無(wú)法滿(mǎn)足要求,則 JVM將報(bào)“out of memory”的錯(cuò)誤,Java應(yīng)用將停止。

    由于是否進(jìn)行主GC由JVM根據(jù)系統(tǒng)環(huán)境決定,而系統(tǒng)環(huán)境在不斷的變化當(dāng)中,所以主GC的運(yùn)行具有不確定性,無(wú)法預(yù)計(jì)它何時(shí)必然出現(xiàn),但可以確定的是對(duì)一個(gè)長(zhǎng)期運(yùn)行的應(yīng)用來(lái)說(shuō),其主GC是反復(fù)進(jìn)行的。

    3.減少GC開(kāi)銷(xiāo)的措施

    根據(jù)上述GC的機(jī)制,程序的運(yùn)行會(huì)直接影響系統(tǒng)環(huán)境的變化,從而影響GC的觸發(fā)。若不針對(duì)GC的特點(diǎn)進(jìn)行設(shè)計(jì)和編碼,就會(huì)出現(xiàn)內(nèi)存駐留等一系列負(fù)面影響。為了避免這些影響,基本的原則就是盡可能地減少垃圾和減少GC過(guò)程中的開(kāi)銷(xiāo)。具體措施包括以下幾個(gè)方面:

    (1)不要顯式調(diào)用System.gc()

    此函數(shù)建議JVM進(jìn)行主GC,雖然只是建議而非一定,但很多情況下它會(huì)觸發(fā)主GC,從而增加主GC的頻率,也即增加了間歇性停頓的次數(shù)。

    (2)盡量減少臨時(shí)對(duì)象的使用

    臨時(shí)對(duì)象在跳出函數(shù)調(diào)用后,會(huì)成為垃圾,少用臨時(shí)變量就相當(dāng)于減少了垃圾的產(chǎn)生,從而延長(zhǎng)了出現(xiàn)上述第二個(gè)觸發(fā)條件出現(xiàn)的時(shí)間,減少了主GC的機(jī)會(huì)。

    (3)對(duì)象不用時(shí)最好顯式置為Null

    一般而言,為Null的對(duì)象都會(huì)被作為垃圾處理,所以將不用的對(duì)象顯式地設(shè)為Null,有利于GC收集器判定垃圾,從而提高了GC的效率。

    (4)盡量使用StringBuffer,而不用String來(lái)累加字符串(詳見(jiàn)blog另一篇文章JAVA中String與StringBuffer)

    由于String是固定長(zhǎng)的字符串對(duì)象,累加String對(duì)象時(shí),并非在一個(gè)String對(duì)象中擴(kuò)增,而是重新創(chuàng)建新的String對(duì)象,如Str5=Str1+Str2+Str3+Str4,這條語(yǔ)句執(zhí)行過(guò)程中會(huì)產(chǎn)生多個(gè)垃圾對(duì)象,因?yàn)閷?duì)次作“+”操作時(shí)都必須創(chuàng)建新的String對(duì)象,但這些過(guò)渡對(duì)象對(duì)系統(tǒng)來(lái)說(shuō)是沒(méi)有實(shí)際意義的,只會(huì)增加更多的垃圾。避免這種情況可以改用StringBuffer來(lái)累加字符串,因StringBuffer是可變長(zhǎng)的,它在原有基礎(chǔ)上進(jìn)行擴(kuò)增,不會(huì)產(chǎn)生中間對(duì)象。

    (5)能用基本類(lèi)型如Int,Long,就不用Integer,Long對(duì)象

    基本類(lèi)型變量占用的內(nèi)存資源比相應(yīng)對(duì)象占用的少得多,如果沒(méi)有必要,最好使用基本變量。

    (6)盡量少用靜態(tài)對(duì)象變量

    靜態(tài)變量屬于全局變量,不會(huì)被GC回收,它們會(huì)一直占用內(nèi)存。

    (7)分散對(duì)象創(chuàng)建或刪除的時(shí)間

    集中在短時(shí)間內(nèi)大量創(chuàng)建新對(duì)象,特別是大對(duì)象,會(huì)導(dǎo)致突然需要大量?jī)?nèi)存,JVM在面臨這種情況時(shí),只能進(jìn)行主GC,以回收內(nèi)存或整合內(nèi)存碎片,從而增加主GC的頻率。集中刪除對(duì)象,道理也是一樣的。它使得突然出現(xiàn)了大量的垃圾對(duì)象,空閑空間必然減少,從而大大增加了下一次創(chuàng)建新對(duì)象時(shí)強(qiáng)制主GC的機(jī)會(huì)。

    4.gc與finalize方法

    ⑴gc方法請(qǐng)求垃圾回收

    使用System.gc()可以不管JVM使用的是哪一種垃圾回收的算法,都可以請(qǐng)求Java的垃圾回收。需要注意的是,調(diào)用System.gc()也僅僅是一個(gè)請(qǐng)求。JVM接受這個(gè)消息后,并不是立即做垃圾回收,而只是對(duì)幾個(gè)垃圾回收算法做了加權(quán),使垃圾回收操作容易發(fā)生,或提早發(fā)生,或回收較多而已。

    ⑵finalize方法透視垃圾收集器的運(yùn)行

    在JVM垃圾收集器收集一個(gè)對(duì)象之前 ,一般要求程序調(diào)用適當(dāng)?shù)姆椒ㄡ尫刨Y源,但在沒(méi)有明確釋放資源的情況下,Java提供了缺省機(jī)制來(lái)終止化該對(duì)象釋放資源,這個(gè)方法就是finalize()。它的原型為:

    protected void finalize() throws Throwable

    在finalize()方法返回之后,對(duì)象消失,垃圾收集開(kāi)始執(zhí)行。原型中的throws Throwable表示它可以?huà)伋鋈魏晤?lèi)型的異常。

    因此,當(dāng)對(duì)象即將被銷(xiāo)毀時(shí),有時(shí)需要做一些善后工作。可以把這些操作寫(xiě)在finalize()方法里。

    以下是引用片段:


    protected void finalize()
      {
      // finalization code here
      }


    ⑶代碼示例

    以下是引用片段:


    class Garbage
      {
      int index;
      static int count;
      Garbage()
      {
      count++;
      System.out.println("object "+count+" construct");
      setID(count);
      }
      void setID(int id)
      {
      index=id;
      }
      protected void finalize() //重寫(xiě)finalize方法
      {
      System.out.println("object "+index+" is reclaimed");
      }
      public static void main(String[] args)
      {
      new Garbage();
      new Garbage();
      new Garbage();
      new Garbage();
      System.gc(); //請(qǐng)求運(yùn)行垃圾收集器
      }
      }


    5.Java 內(nèi)存泄漏

    由于采用了垃圾回收機(jī)制,任何不可達(dá)對(duì)象(對(duì)象不再被引用)都可以由垃圾收集線(xiàn)程回收。因此通常說(shuō)的Java 內(nèi)存泄漏其實(shí)是指無(wú)意識(shí)的、非故意的對(duì)象引用,或者無(wú)意識(shí)的對(duì)象保持。無(wú)意識(shí)的對(duì)象引用是指代碼的開(kāi)發(fā)人員本來(lái)已經(jīng)對(duì)對(duì)象使用完畢,卻因?yàn)榫幋a的錯(cuò)誤而意外地保存了對(duì)該對(duì)象的引用(這個(gè)引用的存在并不是編碼人員的主觀意愿),從而使得該對(duì)象一直無(wú)法被垃圾回收器回收掉,這種本來(lái)以為可以釋放掉的卻最終未能被釋放的空間可以認(rèn)為是被“泄漏了”。
    posted on 2007-10-08 09:02 wilesun 閱讀(352) 評(píng)論(0)  編輯  收藏

    只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 亚洲综合在线成人一区| 国产AV无码专区亚洲AV漫画| 亚洲国产美女精品久久久久| 少妇无码一区二区三区免费| 亚洲AV永久无码精品一百度影院| 精品亚洲永久免费精品| 99久在线国内在线播放免费观看| 精品久久洲久久久久护士免费| 国产免费AV片在线观看| 国产美女在线精品免费观看| 亚洲精品午夜无码专区| 日本一区午夜艳熟免费| 亚洲日本一区二区三区| 视频免费1区二区三区| 国产福利视精品永久免费| 亚洲精品无码久久久| 国产免费黄色无码视频| 久久精品国产亚洲av麻| 97性无码区免费| 亚洲gv白嫩小受在线观看| 最近免费最新高清中文字幕韩国| 亚洲天堂在线视频| 亚洲经典千人经典日产| 美丽的姑娘免费观看在线播放| 中文字幕专区在线亚洲| 一级毛片免费观看| 亚洲性无码一区二区三区| 亚洲?v无码国产在丝袜线观看| 人妻在线日韩免费视频| 亚洲精品无码日韩国产不卡?V| 亚洲人成网亚洲欧洲无码| 亚洲国产婷婷香蕉久久久久久| 午夜精品免费在线观看| 亚洲欧美日韩中文二区| 久久精品女人天堂AV免费观看| 高潮毛片无遮挡高清免费视频| 亚洲午夜福利在线观看| 久99久无码精品视频免费播放| 免费在线看片网站| 777爽死你无码免费看一二区| 亚洲高清专区日韩精品|