《深入理解Java虛擬機(jī)》讀書筆記1

一,java技術(shù)體系

????? *Java程序設(shè)計(jì)語言

????? * 各種硬件平臺上的Java虛擬機(jī)

?????? * Class文件格式

?????? * Java API類庫

?????? * 來自商業(yè)機(jī)構(gòu)和開源社區(qū)的第三方Java類庫

Java程序設(shè)計(jì)語言况鸣、Java虛擬機(jī)碑隆、JavaAPI類庫統(tǒng)稱為JDK(Java Development Kit), JDK是用于支持Java程序開發(fā)的最小環(huán)境。

Java API類庫中的Java SE API子集 和 Java虛擬機(jī)這兩部分統(tǒng)稱為JRE(Java Runtime Environment), JRE是支持Java程序運(yùn)行的標(biāo)準(zhǔn)環(huán)境。

按照J(rèn)ava技術(shù)關(guān)注的重點(diǎn)業(yè)務(wù)領(lǐng)域來劃分,Java技術(shù)體系可以分為四個平臺:

?????? * Java Card : 支持一些Java小程序(Applets)運(yùn)行在小內(nèi)存設(shè)備(如智能卡)上的平臺

? ? ? ? * Java ME(Micro Edition):支持Java程序運(yùn)行在移動終端(手機(jī)呐舔、PDA)上的平臺,對Java API有所精簡慷蠕,并加入了針對移動終端的支持珊拼,這個版本以前稱為J2ME.

? ? ? ? * Java SE(Standard Edition):支持面向桌面級應(yīng)用(如Windows下的應(yīng)用程序)的Java平臺,提供了完整的Java核心API,這個版本以前稱為J2SE.

? ? ? ? * Java EE(Enterprise Edition):支持使用多層架構(gòu)的企業(yè)應(yīng)用(如ERP流炕、CRM應(yīng)用)的Java平臺澎现,除了提供Java SE API外,還對其做了大量的擴(kuò)充并提供了相關(guān)的部署支持每辟,這個版本以前稱為J2EE剑辫。

注:Java EE中的擴(kuò)展一般以javax.*作為包名,而以java.*為包名的包都是Java SE API的核心包渠欺,但由于歷史原因妹蔽,一部分曾經(jīng)是擴(kuò)展包的API后來進(jìn)入了核心包,因此核心包中也包含了不少javax.*的包名挠将。

二胳岂,運(yùn)行時數(shù)據(jù)區(qū)域

??? Java虛擬機(jī)在執(zhí)行Java程序的過程中會把它所管理的內(nèi)存劃分為若干個不同的數(shù)據(jù)區(qū)域。 方法區(qū)(Method Area)捐名、虛擬機(jī)棧(VM Stack)旦万、本地方法棧(Native Method Stack)、堆(Heap)镶蹋、程序計(jì)數(shù)器(Program Couter Register)成艘。

圖一

1.? 程序計(jì)數(shù)器是一塊較小的內(nèi)存空間,它的作用可以看作是當(dāng)前線程所執(zhí)行的字節(jié)碼的行號指示器贺归。字節(jié)碼解釋器工作時就是通過改變這個計(jì)數(shù)器的值來選取下一條需要執(zhí)行的字節(jié)碼指令淆两。

??? Java虛擬機(jī)的多線程是通過線程輪流切換并分配處理器執(zhí)行時間的方式來實(shí)現(xiàn)的。為了線程切換后能恢復(fù)到正確的執(zhí)行位置拂酣,每條線程都需要有一個獨(dú)立的程序計(jì)數(shù)器秋冰,各個線程之間的計(jì)數(shù)器互不影響,獨(dú)立存儲婶熬,我們稱這類內(nèi)存區(qū)域?yàn)椤熬€程私有”的內(nèi)存剑勾。

? ? ? 注:如果線程正在執(zhí)行的是一個Java方法,這個計(jì)數(shù)器記錄的是正在執(zhí)行的虛擬機(jī)字節(jié)碼指令的地址:如果正在執(zhí)行的是Native方法赵颅,這個計(jì)數(shù)器值則為空(Undefined).

? ? ? 注:此內(nèi)存區(qū)域是唯一一個在Java虛擬機(jī)規(guī)范中沒有規(guī)定任何OutOfMemoryError情況的區(qū)域虽另。

2.Java虛擬器棧(Java Virtual Machine Stacks)

???? Java虛擬機(jī)棧也是線程私有的。生命周期與線程相同饺谬,Java虛擬機(jī)棧描述的是Java方法執(zhí)行的內(nèi)存模型:每個方法被執(zhí)行的時候都會同時創(chuàng)建一個棧幀(Stack Frame)捂刺,用于存儲局部變量表、操作棧、動態(tài)鏈接族展、方法出口等信息森缠。

? ? ? 每個方法被調(diào)用直至執(zhí)行完成的過程,就對應(yīng)著一個棧幀在虛擬機(jī)中從入棧到出棧的過程仪缸。

? ? ? 局部變量表存放了編譯器可知的各種基本數(shù)據(jù)類型贵涵、對象引用(可能是一個指向?qū)ο笃鹗嫉刂返囊弥羔槪┖蛂eturnAddress類型(指向一條字節(jié)碼指令的地址)。

? ? ? 局部變量表所需的內(nèi)存空間在編譯期間完成分配腹殿,當(dāng)進(jìn)入一個方法時独悴,這個方法需要在幀中分配多大的局部變量空間是完全確定的,在方法運(yùn)行期間不會改變局部變量表的大小锣尉。

? ? ? Java虛擬器規(guī)范中刻炒,對這個區(qū)域規(guī)定了兩種異常狀況:如果線程請求的棧深度大于虛擬機(jī)所允許的深度,將拋出StackOverflowError異常自沧;如果虛擬機(jī)椃匕拢可以自動擴(kuò)展,當(dāng)擴(kuò)展時無法申請到足夠的內(nèi)存時會拋出OutOfMemoryError異常拇厢。

3.本地方法棧(Native Method Stacks

? ? ? 本地方法棧與虛擬機(jī)棧所發(fā)揮的作用非常類似爱谁。區(qū)別在于虛擬機(jī)棧為虛擬機(jī)執(zhí)行Java方法(也就是字節(jié)碼)服務(wù),而本地方法棧是為虛擬機(jī)使用到的Native方法服務(wù)的孝偎。

? ? ? 本地方法棧也會拋出StackOverflowError和OutOfMemoryError異常

4.Java堆

? ? ? Java堆(Java Heap)是Java虛擬機(jī)所管理的內(nèi)存中最大的一塊访敌。是被所有線程共享的一塊內(nèi)存區(qū)域,在虛擬機(jī)啟動時創(chuàng)建衣盾。此內(nèi)存區(qū)域的唯一目的就是存放對象實(shí)例寺旺。

? ? ? Java虛擬機(jī)規(guī)范規(guī)定:所有的對象實(shí)例以及數(shù)組都要在堆上分配

? ? ? Java堆是垃圾收集器管理的主要區(qū)域势决,因此很多時候也被稱為“GC堆”(Garbage Collected Heap).

? ? ? Java虛擬機(jī)規(guī)范規(guī)定阻塑,Java堆可以處于物理上不連續(xù)的內(nèi)存空間中,只要邏輯上連續(xù)即可果复。

? ? ? 當(dāng)前駐留的虛擬機(jī)都是按照可擴(kuò)展來實(shí)現(xiàn)的(通過-Xmx 和 -Xms控制)陈莽。如果在堆中沒有內(nèi)存完成實(shí)例分配,并且堆也無法再擴(kuò)展時虽抄,將會拋出OutOfMemoryError異常走搁。

5.方法區(qū)

? ? ? 方法區(qū)(Method Area)與Java堆一樣,是各個線程共享的內(nèi)存區(qū)域迈窟,它用于存儲已被虛擬機(jī)加載的類信息朱盐、常量、靜態(tài)變量菠隆、即時編譯器編譯后的代碼等數(shù)據(jù)。

? ? Java虛擬機(jī)規(guī)范規(guī)定,當(dāng)方法區(qū)無法滿足內(nèi)存分配需求時骇径,將拋出OutOfMemoryError異常躯肌。

6.運(yùn)行時常量池

? ? ? 運(yùn)行時常量池(Runtime Constant Pool)是方法區(qū)的一部分。Class文件中除了有類的版本破衔、字段清女、方法、接口等描述信息外晰筛,還有一項(xiàng)信息是常量池(Constant Pool Table)嫡丙,用于存放編譯期生成的各種字面量和符號引用。這部分內(nèi)容將在類加載后存放到方法區(qū)的運(yùn)行時常量池中读第。

? ? ? 運(yùn)行時常量池相對于Class文件常量池的另外一個重要特征是具備動態(tài)性曙博,不僅Class文件中的常量池的內(nèi)容可以進(jìn)入方法區(qū)運(yùn)行時常量池,運(yùn)行期間也可能將新的常量放入池中怜瞒。

7.直接內(nèi)存

直接內(nèi)存(Direct Memory)并不是虛擬機(jī)運(yùn)行時數(shù)據(jù)區(qū)的一部分父泳,也不是Java虛擬機(jī)規(guī)范匯總定義的內(nèi)存區(qū)域,例如, JDK1.4引入的NIO類吴汪,引入了基于通道(Channel)與緩沖區(qū)(Buffer)的I/O方式惠窄,它可以使用Native函數(shù)庫直接分配堆外內(nèi)存,然后通過一個存儲在Java堆里面的DirectByteBuffer對象作為這塊內(nèi)存的引用進(jìn)行操作漾橙。

? ? ? 注意:直接內(nèi)存雖然不包含在堆內(nèi)存中杆融,但是它也是一塊需要的內(nèi)存區(qū)域,因此霜运,在計(jì)算各個內(nèi)存區(qū)域總和的時候要計(jì)算在內(nèi)脾歇。

三、對象訪問

對于Object obj = new Object();

"Object obj"這部分的語義將會反映到Java棧的本地變量表中觉渴,作為一個reference類型數(shù)據(jù)出現(xiàn)介劫。

new Object()”這部分語義將會反映到Java堆中,形成一塊存儲了Object類型所有實(shí)例數(shù)據(jù)值的結(jié)構(gòu)化內(nèi)存案淋。

由于reference類型在Java虛擬機(jī)規(guī)范里面只規(guī)定了一個指向?qū)ο蟮囊米希虼瞬煌奶摂M機(jī)實(shí)現(xiàn)會有不同的實(shí)現(xiàn)對象訪問的方式,主流的訪問方式有兩種:使用句柄 和直接指針踢京。

3.1使用句柄

圖2

使用該方式誉碴,Java堆中將會劃分出一塊內(nèi)存來作為句柄池,reference中存儲的就是對象的句柄地址瓣距,而句柄中存對象實(shí)例數(shù)據(jù)和類型數(shù)據(jù)的具體地址信息黔帕。如上圖2。

3.2使用指針

圖3

reference中直接存儲的就是對象地址蹈丸;

句柄訪問方式最大的好處是reference中存儲的是穩(wěn)定的句柄地址成黄,在對象被移動時只會改變句柄中的實(shí)例數(shù)據(jù)指針呐芥,而reference本身不需要被修改。

直接指針訪問方式的最大好處就是速度更快奋岁,它節(jié)省了一次指針定位的時間開銷思瘟。Sun HotSpot虛擬機(jī)是使用第二種方式的。

4.實(shí)戰(zhàn):OutOfMemoryError異常

1闻伶、Java堆的溢出

??? 通過指定VM Args參數(shù)滨攻,可以設(shè)置虛擬機(jī)的啟動參數(shù)。-Xms參數(shù)指定堆的最小值蓝翰, -Xmx參數(shù)指定堆的最大值光绕,通過參數(shù)-XX:+HeapDumpOnOutOfMemoryError可以讓虛擬機(jī)在出現(xiàn)內(nèi)存溢出異常時Dump出當(dāng)前的內(nèi)存堆轉(zhuǎn)儲文件以便后續(xù)分析。

??? 例如畜份,在VM Arg參數(shù)中指定:-verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:SurvivorRatio=8 -XX:+HeapDumpOnOutOfMemoryError

可以將堆的大小設(shè)置為20M(將堆的最小值-Xms參數(shù)與最大值-Xmx參數(shù)設(shè)置為一樣即可避免堆自動擴(kuò)展)诞帐,并導(dǎo)出Dump文件

如下程序:

圖4

2.虛擬機(jī)棧和本地方法棧溢出

VM Arg中 -Xoss參數(shù)可以設(shè)置本地方法棧大小(由于HotSpot虛擬機(jī)中并不區(qū)分虛擬機(jī)棧和本地方法棧漂坏,因此-Xoss參數(shù)是無效的)景埃,-Xss參數(shù)指定虛擬機(jī)棧的大小

關(guān)于虛擬機(jī)棧和本地方法棧,有兩種可能的異常:StackOverflowError和OutOfMemoryError異常顶别。

實(shí)驗(yàn)表明:在單個線程下谷徙,無論是由于棧幀太大,還是虛擬機(jī)棧容量太小驯绎,當(dāng)內(nèi)存無法分配時完慧,虛擬機(jī)都會拋出StackOverflowError異常,不會拋出OutOfMemoryError異常剩失。

注意:如果是建立過多線程導(dǎo)致的內(nèi)存溢出屈尼,在不能減少線程數(shù)或者更換64位虛擬機(jī)的情況下,就只能通過減少最大堆和減少棧容量來換取更多的線程拴孤。

3.運(yùn)行時常量池溢出(運(yùn)行時常量池屬于方法區(qū)方法區(qū)溢出)

常量池分配在方法區(qū)脾歧。通過-XX:PermSize和-XX:MaxPermSize可以限制方法區(qū)的大小,從而間接限制其中常量池的容量演熟。

圖5

4.方法區(qū)溢出

方法區(qū)用于存放Class的相關(guān)信息鞭执,如類名、訪問修飾符芒粹、常量池兄纺、字段描述、方法描述等化漆。對這個區(qū)域的測試估脆,基本思路是運(yùn)行時產(chǎn)生大量的類去填滿方法區(qū),直到溢出座云。

CGLib (Code Generation Library) 是一個強(qiáng)大的,高性能,高質(zhì)量的Code生成類庫疙赠。它可以在運(yùn)行期擴(kuò)展Java類與實(shí)現(xiàn)Java接口付材。Hibernate用它來實(shí)現(xiàn)PO字節(jié)碼的動態(tài)生成。CGLib 比 Java 的 java.lang.reflect.Proxy 類更強(qiáng)的在于它不僅可以接管接口類的方法棺聊,還可以接管普通類的方法伞租。

CGLib 的底層是Java字節(jié)碼操作框架 —— ASM。

圖6

當(dāng)前的很多主流框架限佩,如Spring和Hibernate對類進(jìn)行增強(qiáng)時,都會使用到CGLib這類字節(jié)碼技術(shù)裸弦,增強(qiáng)的類越多祟同,就需要越大的方法區(qū)來保證動態(tài)生成的Class可以加載如內(nèi)存。

5.本地直接內(nèi)存溢出

DirectMemory容量可通過-XX:MaxDirectMemorySize指定理疙,如果不指定晕城,則默認(rèn)與Java堆的最大值(-Xmx指定)一樣

五、垃圾回收器

垃圾收集(Garbage Collection, GC)窖贤,可以回收堆上的對象砖顷,還可以回收方法區(qū)的“廢棄常量”和“無用的類”

1赃梧、判斷對象是否存活

GC在對堆進(jìn)行回收之前滤蝠,第一件事就是確定哪些對象可以回收。

方案一:引用計(jì)數(shù)算法(Reference Counting)

過程是:給對象中添加一個引用計(jì)數(shù)器授嘀,每當(dāng)有一個地方引用它時物咳,計(jì)數(shù)器值就加1;當(dāng)引用失效時蹄皱,計(jì)數(shù)器值就減1览闰;任何時刻計(jì)數(shù)器都為0的對象就是不可能再被使用的,可以回收巷折。

引用計(jì)數(shù)方案最大的問題是:很難解決對象之間的相互循環(huán)引用的問題压鉴。當(dāng)兩個對象沒有其他對象引用,只是它們之間相互引用對方锻拘,此時這兩個對象已經(jīng)不能再被訪問油吭,但是引用計(jì)數(shù)都不為0;

方案二:根搜索算法(GC Roots Tracing)

思路是:通過一系列的名為“GC Roots”的對象作為起始點(diǎn)逊拍,從這些節(jié)點(diǎn)開始向下搜素上鞠,搜索所走過的路徑稱為引用鏈(Reference Chain),當(dāng)一個對象到GC Roots沒有任何引用鏈相連(用圖論的話來說就是從GC Roots到這個對象不可達(dá))時,則證明此對象是不可用的芯丧。

Java語言里芍阎,可作為GC Roots的對象包括以下幾種:

?????? ** 虛擬機(jī)棧(棧幀中的本地變量表)中的引用的對象

?????? ** 方法區(qū)中的類靜態(tài)屬性引用的對象

?????? ** 方法區(qū)中的常量引用的對象。

?????? ** 本地方法棧中JNI(即一般說的Native方法)的引用的對象缨恒。

2谴咸、引用

在JDK 1.2之前轮听, Java中引用的定義時:如果reference類型的數(shù)據(jù)中存儲的數(shù)值代表的是另外一塊內(nèi)存的起始地址,就稱這塊內(nèi)存代表著一個引用岭佳。

在JDK1.2之后血巍,Java對引用的概念進(jìn)行了擴(kuò)充,將引用分為強(qiáng)引用(Strong Reference)珊随、軟引用(Soft Reference)述寡、弱引用(Weak Reference)、虛引用(Phantom Reference)四種叶洞。這四種引用強(qiáng)度依次逐漸減弱鲫凶。

????? ** 強(qiáng)引用,就是指在程序代碼之中普遍存在的衩辟,類似“Object obj = new Object()”這類的引用螟炫,只要強(qiáng)引用存在,垃圾回收器永遠(yuǎn)不會回收掉被引用的對象艺晴。

? ? ? ? ** 軟引用昼钻, 是指一些有用,但并非必需的對象封寞,對于軟引用關(guān)聯(lián)著的對象然评,在系統(tǒng)將要發(fā)生內(nèi)存溢出異常之前,將會把這些對象列進(jìn)回收范圍之中并進(jìn)行第二次回收钥星。如果這次回收還是沒有足夠的內(nèi)存沾瓦,才會拋出內(nèi)存溢出異常。

? ? ? ? ** 弱引用谦炒,被弱引用關(guān)聯(lián)的對象只能生存到下一次垃圾收集發(fā)生之前贯莺。當(dāng)垃圾收集器工作時,無論當(dāng)前內(nèi)存是否足夠宁改,都會回收掉只被弱引用關(guān)聯(lián)的對象缕探。

? ? ? ? ** 虛引用,一個對象是否有虛引用的存在还蹲,完全不會對其生存時間構(gòu)成影響爹耗,也無法通過虛引用來取得一個對象實(shí)例。為一個對象設(shè)置虛引用關(guān)聯(lián)的唯一目的就是希望能在這個對象被收集器回收時收到一個系統(tǒng)通知谜喊。

3潭兽、關(guān)于對象的死亡的二次標(biāo)記

要真正宣告一個對象死亡,至少要經(jīng)歷兩次標(biāo)記過程:如果對象在進(jìn)行根搜索后發(fā)現(xiàn)是不可達(dá)的斗遏,那么它將會被第一次標(biāo)記并且進(jìn)行一次篩選山卦,篩選的條件是此對象是否有必要執(zhí)行finalize()方法。當(dāng)對象沒有覆蓋finalize()方法或者finalize()方法已經(jīng)被虛擬機(jī)調(diào)用過诵次,這兩種情況將被視為“沒有必要執(zhí)行finalize()”账蓉。

如果一個對象被判定為有必要執(zhí)行finalize()方法枚碗,那么這個對象將會被放置在一個名為F-Queue的隊(duì)列中,并在稍后由一條由虛擬機(jī)自動建立的铸本、低優(yōu)先級的Finalizer線程去執(zhí)行調(diào)用finalize()肮雨,稍后GC將對F-Queue中的對象進(jìn)行第二次小規(guī)模的標(biāo)記,如果對象在finalize()中又重新關(guān)聯(lián)到了GC Roots對象箱玷,那么第二次標(biāo)記時它將被移除出“即將回收”的集合怨规,否則,對象將被回收锡足。

任何一個對象的finalize()方法都只會被系統(tǒng)自動調(diào)用一次椅亚,第二次面臨回收時,它的finalize()方法不會再被調(diào)用舱污。

4、回收方法區(qū)

? ? Java虛擬機(jī)規(guī)范中并沒有要求必須在方法區(qū)實(shí)現(xiàn)垃圾回收弥虐,在方法區(qū)進(jìn)行垃圾收集的“性價比”一般比較低:在堆中扩灯,常規(guī)應(yīng)用進(jìn)行一次垃圾回收一般可以回收70%~80%的空間,而代碼區(qū)(永久代)的垃圾回收效率遠(yuǎn)低于此霜瘪。

代碼區(qū)回收的內(nèi)容有:廢棄常量和無用的類珠插。

回收廢棄常量的方法與回收堆中的對象非常類似,常量池中的其他類(接口)颖对、方法捻撑、字段的符號引用也與此類似。

回收“無用的類”的條件是:同時滿足以下3個條件的類才算是“無用的類”:

????? ** 該類所有的實(shí)例都已經(jīng)被回收缤底,也就是Java堆中不存在該類的任何實(shí)例

???? ? **?加載該類的ClassLoader已經(jīng)被回收顾患。

??? ?? **?該類對應(yīng)的java.lang.Class對象沒有在任何地方被引用,無法在任何地方通過反射訪問該類的方法个唧。

注:是否對類進(jìn)行回收江解,HotSpot虛擬機(jī)提供了-Xnoclassgc參數(shù)進(jìn)行控制,還可以使用-verbose:class及-XX:+TraceClassLoading徙歼、-XX:+TraceClassUnLoading查看類的加載和卸載信息犁河。

六、垃圾回收算法

1魄梯、標(biāo)記-清除算法

“標(biāo)記-清除”算法是最基礎(chǔ)的垃圾回收算法桨螺,之所以說它是最基礎(chǔ)的收集算法,是因?yàn)楹罄m(xù)的收集算法都是基于這種思路并對其缺點(diǎn)進(jìn)行改進(jìn)得到的酿秸。

該算法分為兩個階段:“標(biāo)記”和“清除”灭翔,首先標(biāo)記出所有需要回收的對象,然后在標(biāo)記完成后統(tǒng)一回收掉所有被標(biāo)記的對象允扇。

主要缺點(diǎn)有兩個: 一個是效率問題缠局,標(biāo)記和清除過程的效率都不高则奥;另外一個是空間問題,標(biāo)記清除之后會產(chǎn)生大量不連續(xù)的內(nèi)存碎片,空間碎片太多可能會導(dǎo)致狭园,當(dāng)程序在以后的運(yùn)行過程中需要分配較大對象時無法找到足夠的連續(xù)內(nèi)存而不得不提前觸發(fā)另外一次垃圾回收動作读处。

標(biāo)記-清除

2.復(fù)制算法

為了解決效率問題,出現(xiàn)了“復(fù)制”的收集算法唱矛。

思路是:將可用內(nèi)存按容量劃分為大小相等的兩塊罚舱,每次只使用其中的一塊。當(dāng)這一塊的內(nèi)存用完了绎谦,就將還存活著的對象復(fù)制到另外一塊上面管闷,然后再把已使用過的內(nèi)存空間一次清理掉。

優(yōu)點(diǎn)是:內(nèi)存分配時不用考慮內(nèi)存碎片等復(fù)雜情況窃肠,實(shí)現(xiàn)簡單包个,運(yùn)行高效

缺點(diǎn)是:可利用的內(nèi)存空間縮小為原來的一半,內(nèi)存利用率低冤留。

復(fù)制思路

3.標(biāo)記-整理算法(Mark-Compact)

復(fù)制收集算法在對象存活率較高時就要執(zhí)行較多的復(fù)制操作碧囊,效率將會變低。更關(guān)鍵的是纤怒,如果不想浪費(fèi)50%的空間糯而,就需要有額外的空間進(jìn)行分配擔(dān)保。

算法思路:標(biāo)記過程仍然與“標(biāo)記-清除”算法一樣泊窘,但后續(xù)步驟不是直接對可回收對象進(jìn)行清理熄驼,而是讓所有存活的對象都向一端移動,然后直接清理掉端邊界以外的內(nèi)存烘豹。


標(biāo)記-整理思路

4.分代收集算法(Generational Collection)

該算法只是根據(jù)對象存活周期的不同將內(nèi)存劃分為幾塊瓜贾。一般是把Java堆分為新生代和老年代,這樣就可以根據(jù)各個年代的特點(diǎn)采用最適合的收集算法吴叶。新生代中阐虚,每次來及收集時都發(fā)現(xiàn)有大批對象死去,只有少量存活蚌卤,就選用復(fù)制算法实束。而老年代中因?yàn)閷ο蟠婊盥矢摺]有額外空間對它進(jìn)行分配擔(dān)保逊彭,就必須使用“標(biāo)記-清理”或“標(biāo)記-整理”算法來回收咸灿。

內(nèi)存回收與垃圾收集器在很多時候都是影響系統(tǒng)性能、并發(fā)能力的主要因素之一侮叮,虛擬機(jī)之所以提供多種不同的收集器及大量的調(diào)節(jié)參數(shù)避矢,是因?yàn)橹挥懈鶕?jù)實(shí)際應(yīng)用需求、實(shí)現(xiàn)方式選擇最優(yōu)的收集方式才能獲取最好的性能。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末审胸,一起剝皮案震驚了整個濱河市亥宿,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌砂沛,老刑警劉巖烫扼,帶你破解...
    沈念sama閱讀 219,039評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異碍庵,居然都是意外死亡映企,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評論 3 395
  • 文/潘曉璐 我一進(jìn)店門静浴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來堰氓,“玉大人,你說我怎么就攤上這事苹享∷酰” “怎么了?”我有些...
    開封第一講書人閱讀 165,417評論 0 356
  • 文/不壞的土叔 我叫張陵得问,是天一觀的道長掷邦。 經(jīng)常有香客問我,道長椭赋,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,868評論 1 295
  • 正文 為了忘掉前任或杠,我火速辦了婚禮哪怔,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘向抢。我一直安慰自己认境,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評論 6 392
  • 文/花漫 我一把揭開白布挟鸠。 她就那樣靜靜地躺著叉信,像睡著了一般。 火紅的嫁衣襯著肌膚如雪艘希。 梳的紋絲不亂的頭發(fā)上硼身,一...
    開封第一講書人閱讀 51,692評論 1 305
  • 那天,我揣著相機(jī)與錄音覆享,去河邊找鬼佳遂。 笑死,一個胖子當(dāng)著我的面吹牛撒顿,可吹牛的內(nèi)容都是我干的丑罪。 我是一名探鬼主播,決...
    沈念sama閱讀 40,416評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼吩屹!你這毒婦竟也來了跪另?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,326評論 0 276
  • 序言:老撾萬榮一對情侶失蹤煤搜,失蹤者是張志新(化名)和其女友劉穎免绿,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體宅楞,經(jīng)...
    沈念sama閱讀 45,782評論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡针姿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了厌衙。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片距淫。...
    茶點(diǎn)故事閱讀 40,102評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖婶希,靈堂內(nèi)的尸體忽然破棺而出榕暇,到底是詐尸還是另有隱情,我是刑警寧澤喻杈,帶...
    沈念sama閱讀 35,790評論 5 346
  • 正文 年R本政府宣布彤枢,位于F島的核電站,受9級特大地震影響筒饰,放射性物質(zhì)發(fā)生泄漏缴啡。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評論 3 331
  • 文/蒙蒙 一瓷们、第九天 我趴在偏房一處隱蔽的房頂上張望业栅。 院中可真熱鬧,春花似錦谬晕、人聲如沸碘裕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽帮孔。三九已至,卻和暖如春不撑,著一層夾襖步出監(jiān)牢的瞬間文兢,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評論 1 272
  • 我被黑心中介騙來泰國打工焕檬, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留禽作,地道東北人。 一個月前我還...
    沈念sama閱讀 48,332評論 3 373
  • 正文 我出身青樓揩页,卻偏偏與公主長得像旷偿,于是被迫代替她去往敵國和親烹俗。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評論 2 355

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