《Java編程思想》筆記——初始化與清理

1.Java類的初始化順序

對象的創(chuàng)建過程:

  1. 即使沒有顯式地使用static關(guān)鍵字属提,構(gòu)造器實際上也是靜態(tài)方法权逗。因此,首次創(chuàng)建類型的對象時冤议,或者靜態(tài)方法/靜態(tài)字段首次被訪問時斟薇,Java解釋器必須查找類路徑,以定位.class文件恕酸。
  2. 然后載入.class堪滨,有關(guān)靜態(tài)初始化的所有動作都會執(zhí)行。因此蕊温,靜態(tài)初始化只在Class對象首次加載的時候進(jìn)行一次袱箱。
  3. 當(dāng)創(chuàng)建對象時,首先將在堆上為對象分配足夠的存儲空間义矛。
  4. 這塊存儲空間會被清零发笔,這就自動為對象中所有的基本數(shù)據(jù)類型都設(shè)置了默認(rèn)值,而引用則被設(shè)置成了null凉翻。
  5. 執(zhí)行所有出現(xiàn)于字段定義處的初始化動作筐咧。
  6. 執(zhí)行構(gòu)造器。

初始化規(guī)則:

  1. 在一個類中噪矛,初始化順序由變量在類中的聲明定義順序決定量蕊,成員變量的初始化發(fā)生在方法調(diào)用之前,包括構(gòu)造方法艇挨;
  2. 靜態(tài)變量的初始化發(fā)生在需要使用的時候残炮,一旦被初始化之后,靜態(tài)變量就不會再初始化缩滨;
  3. 靜態(tài)初始化塊和靜態(tài)變量類似的執(zhí)行也在構(gòu)造方法之前势就,并且僅執(zhí)行一次;
  4. 動態(tài)初始化塊(與靜態(tài)初始化塊類似脉漏,只是沒有static關(guān)鍵字劲赠,即放在一對大括號中的代碼塊)在靜態(tài)初始化塊初始化結(jié)束后執(zhí)行,動態(tài)初始化塊每次創(chuàng)建新對象都會初始化一次续滋;
  5. 基類的構(gòu)造器總是在導(dǎo)出類的構(gòu)造過程中被調(diào)用躯枢,而且按照繼承層次逐漸向上鏈接,以使每個基類的構(gòu)造器都能得到調(diào)用司忱;

綜述皇忿,類的初始化順序依次為:

  1. 父類的靜態(tài)變量/靜態(tài)初始化塊畴蹭;
  2. 子類類的靜態(tài)變量/靜態(tài)初始化塊;
  3. 父類的動態(tài)初始化塊鳍烁、成員變量初始化叨襟;
  4. 子類的動態(tài)初始化塊、成員變量初始化幔荒;
  5. 父類的構(gòu)造方法糊闽;
  6. 子類的構(gòu)造方法;

2.java中5個存放數(shù)據(jù)的地方:

  1. 寄存器(Registers):位于CPU內(nèi)部爹梁,是速度最快的存儲區(qū)墓怀,但是數(shù)量和容量有限。在java中不能直接操作寄存器卫键。

  2. 棧(Stack):棧位于通用隨機(jī)訪問存儲器 (General random-access memory傀履,RAM,內(nèi)存) 中莉炉,通過處理器的棧指針訪問钓账,棧指針從棧頂向棧底分配內(nèi)存,從棧底向棧頂釋放內(nèi)存絮宁。棧是僅次于寄存器的速度第二快的存儲器梆暮,在java程序中,一般的8種基本類型數(shù)據(jù)對象的引用通常存放在棧內(nèi)存中绍昂,不通過new關(guān)鍵字的字符串對象也是存放在棧的字符串池中啦粹。棧的優(yōu)勢是,存取速度比堆要快窘游,僅次于寄存器唠椭,棧數(shù)據(jù)可以共享。但缺點是忍饰,存在棧中的數(shù)據(jù)大小與生存期必須是確定的贪嫂,缺乏靈活性。

  3. 堆(Heap):也是位于通用隨機(jī)訪問存儲器 (General random-access memory艾蓝,RAM力崇,內(nèi)存) 中的共享內(nèi)存池。Java的堆是一個運(yùn)行時數(shù)據(jù)區(qū)赢织,類的對象從中分配空間亮靴,凡是通過new關(guān)鍵字創(chuàng)建的對象都存放在堆內(nèi)存中,它們不需要程序代碼來顯式的釋放于置。堆是由垃圾回收來負(fù)責(zé)的茧吊,堆的優(yōu)勢是可以動態(tài)地分配內(nèi)存大小,生存期也不必事先告訴編譯器,因為它是在運(yùn)行時動態(tài)分配內(nèi)存的饱狂,Java的垃圾收集器會自動收走這些不再使用的數(shù)據(jù)。但缺點是宪彩,由于要在運(yùn)行時動態(tài)分配內(nèi)存休讳,存取速度較慢。

  4. 常量存儲器(Constant storage):java中的常量是存放在系統(tǒng)內(nèi)嵌的只讀存儲器中(read-only memory,ROM)的尿孔。

  5. 非RAM存儲器(Non-RAM storage):對于流對象和持久化對象俊柔,通常存放在程序外的存儲器,如硬盤活合。

3.java中的終結(jié)處理

Java中沒有像C/C++的析構(gòu)函數(shù)雏婶,用來銷毀不用的對象釋放內(nèi)存空間,只有以下三個方法用于通知垃圾回收器回收對象:

  1. finalize()只是通知JVM的垃圾收集器當(dāng)前的對象不再使用可以被回收了白指,但是垃圾回收器根據(jù)內(nèi)存使用狀況來決定是否回收留晚。
    finalize()最有用的地方是在JNI調(diào)用本地方法時(C/C++方法),調(diào)用本地方法的析構(gòu)函數(shù)消耗對象釋放函數(shù)告嘲。
  2. System.gc()是強(qiáng)制進(jìn)行終結(jié)動作错维,顯式通知垃圾回收器釋放內(nèi)存,但是垃圾回收器也不一定會立即執(zhí)行橄唬,垃圾回收器根據(jù)當(dāng)前內(nèi)存使用狀況和對象的生命周期自行決定是否回收赋焕。
  3. RunTime.getRunTime().gc()和System.gc()類似。

注意:這三個函數(shù)都不能保證垃圾回收器立即執(zhí)行仰楚,推薦不要頻繁使用隆判。
垃圾回收器只知道釋放那些經(jīng)由new分配的內(nèi)存,并且僅僅在程序瀕臨存儲空間用完才會釋放僧界。

4.垃圾回收器原理:

  1. 引用計數(shù)(ReferenceCounting)垃圾回收算法:
    一種簡單但是速度較慢的垃圾回收算法侨嘀,每個對象擁有一個引用計數(shù)器(Reference Counter),當(dāng)每次引用附加到這個對象時捂襟,對象的引用計數(shù)器加1飒炎。當(dāng)每次引用超出作用范圍或者被設(shè)置為null時,對象的引用計數(shù)器減1笆豁。垃圾回收器遍歷整個對象列表郎汪,當(dāng)發(fā)現(xiàn)一個對象的引用計數(shù)器為0時,將該對象移出內(nèi)存釋放闯狱。
  • 引用計數(shù)算法的缺點是煞赢,當(dāng)對象環(huán)狀相互引用時,對象的引用計數(shù)器總不為0哄孤,要想回收這些對象需要額外的處理照筑。
  • 引用計數(shù)算法只是用來解釋垃圾回收器的工作原理,沒有JVM使用它實現(xiàn)垃圾回收器
  • 引用計數(shù)的改進(jìn)算法:
    任何存活的對象必須被在靜態(tài)存儲區(qū)或者棧(Stack)中的引用所引用凝危,因此當(dāng)遍歷全部靜態(tài)存儲區(qū)或棧中的引用時波俄,即可以確定所有存活的對象。每當(dāng)遍歷一個引用時蛾默,檢查該引用所指向的對象懦铺,同時檢查該對象上的所有引用,沒有引用指向的對象和相互自引用的對象將被垃圾回收器回收支鸡。
  1. 暫停復(fù)制(stop-and-copy)算法:
    垃圾回收器的收集機(jī)制基于:任何一個存活的對象必須要被一個存儲在椂睿或者靜態(tài)存儲區(qū)的引用所引用。
    暫停復(fù)制的算法是:程序在運(yùn)行過程中首先暫停執(zhí)行牧挣,把每個存活的對象從一個堆復(fù)制到另一個堆中急前,已經(jīng)不再被使用的對象被回收而不再復(fù)制。
    暫停復(fù)制算法有兩個問題:
  • 第一個問題是必須要同時維護(hù)分離的兩個堆瀑构,需要程序運(yùn)行所需兩倍的內(nèi)存空間裆针。JVM的解決辦法是在內(nèi)存塊中分配堆空間,復(fù)制時簡單地從一個內(nèi)存塊復(fù)制到另一個內(nèi)存塊寺晌;

  • 第二個問題是復(fù)制過程的本身處理据块,當(dāng)程序運(yùn)行穩(wěn)定以后,只會產(chǎn)生很少的垃圾對象需要回收折剃,如果垃圾回收器還是頻繁地復(fù)制存活對象是非常低性能的另假。JVM的解決方法是使用一種新的垃圾回收算法——標(biāo)記清除(mark-and-sweep)。
    一般來說標(biāo)記清除算法在正常的使用場景中速度比較慢怕犁,但是當(dāng)程序只產(chǎn)生很少的垃圾對象需要回收時边篮,該算法就非常的高效。

  1. 標(biāo)記清除(mark-and-sweep)算法:
    和暫停復(fù)制的邏輯類似奏甫,標(biāo)記清除算法從棧和靜態(tài)存儲區(qū)開始追蹤所有引用尋找存活的對象戈轿,當(dāng)每次找到一個存活的對象時,對象被設(shè)置一個標(biāo)記并且不被回收阵子,當(dāng)標(biāo)記過程完成后思杯,清除不用的死對象,釋放內(nèi)存空間挠进。
    標(biāo)記清除算法不需要復(fù)制對象色乾,所有的標(biāo)記和清除工作在一個內(nèi)存堆中完成。
    注意:SUN的文檔中說JVM的垃圾回收器是一個后臺運(yùn)行的低優(yōu)先級進(jìn)程领突,但是在早期版本的JVM中并不是這樣實現(xiàn)的暖璧,當(dāng)內(nèi)存不夠用時,垃圾回收器先暫停程序運(yùn)行君旦,然后進(jìn)行垃圾回收澎办。

  2. 分代復(fù)制(generation-copy)算法:
    一種對暫停復(fù)制算法的改進(jìn)嘲碱,JVM分配內(nèi)存是按塊分配的,當(dāng)創(chuàng)建一個大對象時局蚀,需要占用一塊內(nèi)存空間麦锯,嚴(yán)格的暫停復(fù)制算法在釋放老內(nèi)存堆之前要求把每個存活的對象從源堆拷貝到新堆,這樣做非常的消耗內(nèi)存琅绅。
    通過內(nèi)存堆扶欣,垃圾回收器可以將對象拷貝到回收對象的內(nèi)存堆中,每個內(nèi)存塊擁有一個世代計數(shù)(generation count)用于標(biāo)記對象是否存活奉件。每個內(nèi)存塊通過對象被引用獲得世代計數(shù)宵蛀,一般情況下只有當(dāng)最老的內(nèi)存塊被回收時才會創(chuàng)建新的內(nèi)存塊昆著,這主要用于處理大量的短存活周期臨時對象回收問題县貌。一次完整的清理過程中,內(nèi)存塊中的大對象不會被復(fù)制凑懂,只是根據(jù)引用重新獲得世代計數(shù)煤痕。

JVM監(jiān)控垃圾回收器的效率,當(dāng)發(fā)現(xiàn)所有的對象都是長時間存活時接谨,JVM將垃圾回收器的收集算法調(diào)整為標(biāo)記清除摆碉;當(dāng)內(nèi)存堆變得零散碎片時,JVM又重新將垃圾回收器的算法切換會暫停復(fù)制脓豪,這就是JVM的自適應(yīng)分代暫停復(fù)制標(biāo)記清除垃圾回收算法的思想巷帝。


持續(xù)完善補(bǔ)充!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末扫夜,一起剝皮案震驚了整個濱河市楞泼,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌笤闯,老刑警劉巖堕阔,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異颗味,居然都是意外死亡超陆,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進(jìn)店門浦马,熙熙樓的掌柜王于貴愁眉苦臉地迎上來时呀,“玉大人,你說我怎么就攤上這事晶默⊥诉耄” “怎么了?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵荤胁,是天一觀的道長瞧预。 經(jīng)常有香客問我屎债,道長,這世上最難降的妖魔是什么垢油? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任盆驹,我火速辦了婚禮,結(jié)果婚禮上滩愁,老公的妹妹穿的比我還像新娘躯喇。我一直安慰自己,他們只是感情好硝枉,可當(dāng)我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布廉丽。 她就那樣靜靜地躺著,像睡著了一般妻味。 火紅的嫁衣襯著肌膚如雪正压。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天责球,我揣著相機(jī)與錄音焦履,去河邊找鬼。 笑死雏逾,一個胖子當(dāng)著我的面吹牛嘉裤,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播栖博,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼屑宠,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了仇让?” 一聲冷哼從身側(cè)響起典奉,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎妹孙,沒想到半個月后秋柄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡蠢正,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年骇笔,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嚣崭。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡笨触,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出雹舀,到底是詐尸還是另有隱情芦劣,我是刑警寧澤,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布说榆,位于F島的核電站虚吟,受9級特大地震影響寸认,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜串慰,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一偏塞、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧邦鲫,春花似錦灸叼、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至滔以,卻和暖如春捉腥,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背醉者。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工但狭, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留披诗,地道東北人撬即。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像呈队,于是被迫代替她去往敵國和親剥槐。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,933評論 2 355

推薦閱讀更多精彩內(nèi)容