摘要:而使用虛擬機(jī)是實(shí)現(xiàn)這一特點(diǎn)的關(guān)鍵。每個(gè)字節(jié)碼指令都由一個(gè)字節(jié)的操作碼和附加的操作數(shù)組成。字節(jié)碼可以通過(guò)以下兩種方式轉(zhuǎn)換成合適的語(yǔ)言解釋器一條一條地讀取,解釋并執(zhí)行字節(jié)碼執(zhí)行,所以它可以很快地解釋字節(jié)碼,但是執(zhí)行起來(lái)會(huì)比較慢。
一、什么是JVM
JVM是Java Virtual Machine(Java 虛擬機(jī))的縮寫(xiě),JVM是一種用于計(jì)算設(shè)備的規(guī)范,它是一個(gè)虛構(gòu)出來(lái)的計(jì)算機(jī),是通過(guò)在實(shí)際的計(jì)算機(jī)上仿真模擬各種計(jì)算機(jī)功能來(lái)實(shí)現(xiàn)的。
Java語(yǔ)言的一個(gè)非常重要的特點(diǎn)就是平臺(tái)無(wú)關(guān)性。而使用Java虛擬機(jī)是實(shí)現(xiàn)這一特點(diǎn)的關(guān)鍵。一般的高級(jí)語(yǔ)言如果要在不同的平臺(tái)上運(yùn)行,至少需要編譯成不同的目標(biāo)代碼。而引入Java語(yǔ)言虛擬機(jī)后,Java語(yǔ)言在不同平臺(tái)上運(yùn)行時(shí)不需要重新編譯。Java語(yǔ)言使用Java虛擬機(jī)屏蔽了與具體平臺(tái)相關(guān)的信息,使得Java語(yǔ)言編譯程序只需生成在Java虛擬機(jī)上運(yùn)行的目標(biāo)代碼(字節(jié)碼),就可以在多種平臺(tái)上不加修改地運(yùn)行。Java虛擬機(jī)在執(zhí)行字節(jié)碼時(shí),把字節(jié)碼解釋成具體平臺(tái)上的機(jī)器指令執(zhí)行。這就是Java的能夠“一次編譯,到處運(yùn)行”的原因。
二、JVM總體概述JVM總體上是由類(lèi)裝載子系統(tǒng)(ClassLoader)、運(yùn)行時(shí)數(shù)據(jù)區(qū)、執(zhí)行引擎、垃圾收集這四個(gè)部分組成。其中我們最為關(guān)注的運(yùn)行時(shí)數(shù)據(jù)區(qū),也就是JVM的內(nèi)存部分則是由方法區(qū)(Method Area)、JAVA堆(Java Heap)、虛擬機(jī)棧(JVM Stack)、程序計(jì)數(shù)器、本地方法棧(Native Method Stack)這幾部分組成。
三、JVM體系結(jié)構(gòu) 3.1 類(lèi)裝載子系統(tǒng)Class Loader類(lèi)加載器負(fù)責(zé)加載.class文件,class文件在文件開(kāi)頭有特定的文件標(biāo)示,并且ClassLoader負(fù)責(zé)class文件的加載等,至于它是否可以運(yùn)行,則由Execution Engine決定。
3.2 運(yùn)行時(shí)數(shù)據(jù)區(qū)棧管運(yùn)行,堆管存儲(chǔ)。JVM調(diào)優(yōu)主要是優(yōu)化Java堆和方法區(qū)。
3.2.1 方法區(qū)(Method Area)方法區(qū)是各線程共享的內(nèi)存區(qū)域,它用于存儲(chǔ)已被JVM加載的類(lèi)信息、常量、靜態(tài)變量、運(yùn)行時(shí)常量池等數(shù)據(jù)。
3.2.2 Java堆(Java Heap)Java堆是各線程共享的內(nèi)存區(qū)域,在JVM啟動(dòng)時(shí)創(chuàng)建,這塊區(qū)域是JVM中最大的, 用于存儲(chǔ)應(yīng)用的對(duì)象和數(shù)組,也是GC主要的回收區(qū),一個(gè) JVM 實(shí)例只存在一個(gè)堆內(nèi)存,堆內(nèi)存的大小是可以調(diào)節(jié)的。類(lèi)加載器讀取了類(lèi)文件后,需要把類(lèi)、方法、常變量放到堆內(nèi)存中,以方便執(zhí)行器執(zhí)行,堆內(nèi)存分為三部分:新生代、老年代、永久代。
說(shuō)明:
Jdk1.6及之前:常量池分配在永久代 。
Jdk1.7:有,但已經(jīng)逐步“去永久代” 。
Jdk1.8及之后:無(wú)永久代,改用元空間代替(java.lang.OutOfMemoryError: PermGen space,這種錯(cuò)誤將不會(huì)出現(xiàn)在JDK1.8中)。
3.2.3 Java棧(JVM Stack)1) 棧是什么
Java棧是線程私有的,是在線程創(chuàng)建時(shí)創(chuàng)建,它的生命期是跟隨線程的生命期,線程結(jié)束棧內(nèi)存也就釋放,對(duì)于棧來(lái)說(shuō)不存在垃圾回收問(wèn)題,只要線程一結(jié)束該棧就Over,生命周期和線程一致。基本類(lèi)型的變量和對(duì)象的引用變量都是在函數(shù)的棧內(nèi)存中分配。
2) 棧存儲(chǔ)什么
每個(gè)方法執(zhí)行的時(shí)候都會(huì)創(chuàng)建一個(gè)棧幀,棧幀中主要存儲(chǔ)3類(lèi)數(shù)據(jù):
局部變量表:輸入?yún)?shù)和輸出參數(shù)以及方法內(nèi)的變量;
棧操作:記錄出棧和入棧的操作;
棧幀數(shù)據(jù):包括類(lèi)文件、方法等等。
3) 棧運(yùn)行原理
棧中的數(shù)據(jù)都是以棧幀的格式存在,棧幀是一個(gè)內(nèi)存區(qū)塊,是一個(gè)數(shù)據(jù)集,是一個(gè)有關(guān)方法和運(yùn)行期數(shù)據(jù)的數(shù)據(jù)集。每一個(gè)方法被調(diào)用直至執(zhí)行完成的過(guò)程,就對(duì)應(yīng)著一個(gè)棧幀在棧中從入棧到出棧的過(guò)程。
4) 本地方法棧(Native Method Stack)
本地方法棧和JVM棧發(fā)揮的作用非常相似,也是線程私有的,區(qū)別是JVM棧為JVM執(zhí)行Java方法(也就是字節(jié)碼)服務(wù),而本地方法棧為JVM使用到的Native方法服務(wù)。它的具體做法是在本地方法棧中登記native方法,在執(zhí)行引擎執(zhí)行時(shí)加載Native Liberies.有的虛擬機(jī)(比如Sun Hotpot)直接把兩者合二為一。
5) 程序計(jì)數(shù)器(Program Counter Register)
程序計(jì)數(shù)器是一塊非常小的內(nèi)存空間,幾乎可以忽略不計(jì),每個(gè)線程都有一個(gè)程序計(jì)算器,是線程私有的,可以看作是當(dāng)前線程所執(zhí)行的字節(jié)碼的行號(hào)指示器,指向方法區(qū)中的方法字節(jié)碼(下一個(gè)將要執(zhí)行的指令代碼),由執(zhí)行引擎讀取下一條指令。
6) 運(yùn)行時(shí)常量池
運(yùn)行時(shí)常量池是方法區(qū)的一部分,用于存放編譯器生成的各種字面量和符號(hào)引用,這部分內(nèi)容將在類(lèi)加載后存放到方法區(qū)的運(yùn)行時(shí)常量池中。相較于Class文件常量池,運(yùn)行時(shí)常量池更具動(dòng)態(tài)性,在運(yùn)行期間也可以將新的變量放入常量池中,而不是一定要在編譯時(shí)確定的常量才能放入。最主要的運(yùn)用便是String類(lèi)的intern()方法。
3.3 執(zhí)行引擎(Execution Engine)執(zhí)行引擎執(zhí)行包在裝載類(lèi)的方法中的指令,也就是方法。執(zhí)行引擎以指令為單位讀取Java字節(jié)碼。它就像一個(gè)CPU一樣,一條一條地執(zhí)行機(jī)器指令。每個(gè)字節(jié)碼指令都由一個(gè)1字節(jié)的操作碼和附加的操作數(shù)組成。執(zhí)行引擎取得一個(gè)操作碼,然后根據(jù)操作數(shù)來(lái)執(zhí)行任務(wù),完成后就繼續(xù)執(zhí)行下一條操作碼。
不過(guò)Java字節(jié)碼是用一種人類(lèi)可以讀懂的語(yǔ)言編寫(xiě)的,而不是用機(jī)器可以直接執(zhí)行的語(yǔ)言。因此,執(zhí)行引擎必須把字節(jié)碼轉(zhuǎn)換成可以直接被JVM執(zhí)行的語(yǔ)言。字節(jié)碼可以通過(guò)以下兩種方式轉(zhuǎn)換成合適的語(yǔ)言:
解釋器: 一條一條地讀取,解釋并執(zhí)行字節(jié)碼執(zhí)行,所以它可以很快地解釋字節(jié)碼,但是執(zhí)行起來(lái)會(huì)比較慢。這是解釋執(zhí)行語(yǔ)言的一個(gè)缺點(diǎn)。
即時(shí)編譯器:用來(lái)彌補(bǔ)解釋器的缺點(diǎn),執(zhí)行引擎首先按照解釋執(zhí)行的方式來(lái)執(zhí)行,然后在合適的時(shí)候,即時(shí)編譯器把整段字節(jié)碼編譯成本地代碼。然后,執(zhí)行引擎就沒(méi)有必要再去解釋執(zhí)行方法了,它可以直接通過(guò)本地代碼去執(zhí)行。執(zhí)行本地代碼比一條一條進(jìn)行解釋執(zhí)行的速度快很多,編譯后的代碼可以執(zhí)行的很快,因?yàn)楸镜卮a是保存在緩存里的。
3.4 垃圾收集(Garbage Collection, GC) 3.4.1 什么是垃圾收集垃圾收集即垃圾回收,簡(jiǎn)單的說(shuō)垃圾回收就是回收內(nèi)存中不再使用的對(duì)象。所謂使用中的對(duì)象(已引用對(duì)象),指的是程序中有指針指向的對(duì)象;而未使用中的對(duì)象(未引用對(duì)象),則沒(méi)有被任何指針給指向,因此占用的內(nèi)存也可以被回收掉。
垃圾回收的基本步驟分兩步:
查找內(nèi)存中不再使用的對(duì)象(GC判斷策略)
釋放這些對(duì)象占用的內(nèi)存(GC收集算法)
3.4.2 GC判斷策略1) 引用計(jì)數(shù)算法
引用計(jì)數(shù)算法是給對(duì)象添加一個(gè)引用計(jì)數(shù)器,每當(dāng)有一個(gè)引用它時(shí),計(jì)數(shù)器值就加1;當(dāng)引用失效時(shí),計(jì)數(shù)器值就減1;任何時(shí)刻計(jì)數(shù)器都為0的對(duì)象就是不可能再被使用的對(duì)象。缺點(diǎn):很難解決對(duì)象之間相互循環(huán)引用的問(wèn)題。
2) 根搜索算法
根搜索算法的基本思路就是通過(guò)一系列名為“GC Roots”的對(duì)象作為起始點(diǎn),從這些節(jié)點(diǎn)開(kāi)始向下搜索,搜索所走過(guò)的路徑稱(chēng)為引用鏈(Reference Chain),當(dāng)一個(gè)對(duì)象到GC Roots沒(méi)有任何引用鏈相連(也就是說(shuō)從GC Roots到這個(gè)對(duì)象不可達(dá))時(shí),則證明此對(duì)象是不可用的。
在Java語(yǔ)言里,可作為GC Roots的對(duì)象包括以下幾種:
虛擬機(jī)棧(棧幀中的本地變量表)中引用的對(duì)象;
方法區(qū)中類(lèi)靜態(tài)屬性引用的對(duì)象;
方法區(qū)中常量應(yīng)用的對(duì)象;
本地方法棧中JNI(Native方法)引用的對(duì)象。
注:在根搜索算法中不可達(dá)的對(duì)象,也并非是“非死不可”的,因?yàn)橐嬲嬉粋€(gè)對(duì)象死亡,至少要經(jīng)歷兩次標(biāo)記過(guò)程:第一次是標(biāo)記沒(méi)有與GC Roots相連接的引用鏈;第二次是GC對(duì)在F-Queue執(zhí)行隊(duì)列中的對(duì)象進(jìn)行的小規(guī)模標(biāo)記(對(duì)象需要覆蓋finalize()方法且沒(méi)被調(diào)用過(guò))。
3.4.3 GC收集算法1) 標(biāo)記-清除算法(Mark-Sweep)
標(biāo)記-清楚算法采用從根集合(GC Roots)進(jìn)行掃描,首先標(biāo)記出所有需要回收的對(duì)象(根搜索算法),標(biāo)記完成后統(tǒng)一回收掉所有被標(biāo)記的對(duì)象。
該算法有兩個(gè)問(wèn)題:
效率問(wèn)題:標(biāo)記和清除過(guò)程的效率都不高;
空間問(wèn)題:標(biāo)記清除后會(huì)產(chǎn)生大量不連續(xù)的內(nèi)存碎片, 空間碎片太多可能會(huì)導(dǎo)致在運(yùn)行過(guò)程中需要分配較大對(duì)象時(shí)無(wú)法找到足夠的連續(xù)內(nèi)存而不得不提前觸發(fā)另一次垃圾收集。
2) 復(fù)制算法(Copying)
復(fù)制算法是將可用內(nèi)存按容量劃分為大小相等的兩塊, 每次只用其中一塊, 當(dāng)這一塊的內(nèi)存用完, 就將還存活的對(duì)象復(fù)制到另外一塊上面, 然后把已使用過(guò)的內(nèi)存空間一次清理掉。
3) 標(biāo)記-整理算法(Mark-Compact)
標(biāo)記整理算法的標(biāo)記過(guò)程與標(biāo)記清除算法相同, 但后續(xù)步驟不再對(duì)可回收對(duì)象直接清理, 而是讓所有存活的對(duì)象都向一端移動(dòng),然后清理掉端邊界以外的內(nèi)存。
4) 分代收集算法(Generational Collection)
分代收集算法是目前大部分JVM的垃圾收集器采用的算法。它的核心思想是根據(jù)對(duì)象存活的生命周期將內(nèi)存劃分為若干個(gè)不同的區(qū)域。一般情況下將堆區(qū)劃分為老年代(Tenured Generation)和新生代(Young Generation),在堆區(qū)之外還有一個(gè)代就是永久代(Permanet Generation)。老年代的特點(diǎn)是每次垃圾收集時(shí)只有少量對(duì)象需要被回收,而新生代的特點(diǎn)是每次垃圾回收時(shí)都有大量的對(duì)象需要被回收,那么就可以根據(jù)不同代的特點(diǎn)采取最適合的收集算法。
新生代(Young Generation)的回收算法(以復(fù)制算法為主)
所有新生成的對(duì)象首先都是放在年輕代的。年輕代的目標(biāo)就是盡可能快速的收集掉那些生命周期短的對(duì)象。
新生代內(nèi)存按照8:1:1的比例分為一個(gè)eden區(qū)和兩個(gè)survivor(survivor0,survivor1)區(qū)。一個(gè)Eden區(qū),兩個(gè) Survivor區(qū)(一般而言)。大部分對(duì)象在Eden區(qū)中生成。回收時(shí)先將eden區(qū)存活對(duì)象復(fù)制到一個(gè)survivor0區(qū),然后清空eden區(qū),當(dāng)這個(gè)survivor0區(qū)也存放滿(mǎn)了時(shí),則將eden區(qū)和survivor0區(qū)存活對(duì)象復(fù)制到另一個(gè)survivor1區(qū),然后清空eden和這個(gè)survivor0區(qū),此時(shí)survivor0區(qū)是空的,然后將survivor0區(qū)和survivor1區(qū)交換,即保持survivor1區(qū)為空, 如此往復(fù)。
當(dāng)survivor1區(qū)不足以存放 eden和survivor0的存活對(duì)象時(shí),就將存活對(duì)象直接存放到老年代。若是老年代也滿(mǎn)了就會(huì)觸發(fā)一次Full GC(Major GC),也就是新生代、老年代都進(jìn)行回收。
新生代發(fā)生的GC也叫做Minor GC,MinorGC發(fā)生頻率比較高(不一定等Eden區(qū)滿(mǎn)了才觸發(fā))。
老年代(Tenured Generation)的回收算法(以標(biāo)記-清除、標(biāo)記-整理為主)
在年輕代中經(jīng)歷了N次垃圾回收后仍然存活的對(duì)象,就會(huì)被放到老年代中。因此,可以認(rèn)為老年代中存放的都是一些生命周期較長(zhǎng)的對(duì)象。
內(nèi)存比新生代也大很多(大概比例是1:2),當(dāng)老年代內(nèi)存滿(mǎn)時(shí)觸發(fā)Major GC即Full GC,F(xiàn)ull GC發(fā)生頻率比較低,老年代對(duì)象存活時(shí)間比較長(zhǎng),存活率標(biāo)記高。
永久代(Permanet Generation)的回收算法
用于存放靜態(tài)文件,如Java類(lèi)、方法等。永久代對(duì)垃圾回收沒(méi)有顯著影響,但是有些應(yīng)用可能動(dòng)態(tài)生成或者調(diào)用一些class,例如Hibernate 等,在這種時(shí)候需要設(shè)置一個(gè)比較大的永久代空間來(lái)存放這些運(yùn)行過(guò)程中新增的類(lèi)。永久代也稱(chēng)方法區(qū)。方法區(qū)主要回收的內(nèi)容有:廢棄常量和無(wú)用的類(lèi)。對(duì)于廢棄常量也可通過(guò)根搜索算法來(lái)判斷,但是對(duì)于無(wú)用的類(lèi)則需要同時(shí)滿(mǎn)足下面3個(gè)條件:
該類(lèi)所有的實(shí)例都已經(jīng)被回收,也就是Java堆中不存在該類(lèi)的任何實(shí)例;
加載該類(lèi)的ClassLoader已經(jīng)被回收;
該類(lèi)對(duì)應(yīng)的java.lang.Class對(duì)象沒(méi)有在任何地方被引用,無(wú)法在任何地方通過(guò)反射訪問(wèn)該類(lèi)的方法。
3.4.4 垃圾收集器1) Serial收集器(復(fù)制算法)
新生代單線程收集器,標(biāo)記和清理都是單線程,優(yōu)點(diǎn)是簡(jiǎn)單高效。是client級(jí)別默認(rèn)的GC方式,可以通過(guò)-XX:+UseSerialGC來(lái)強(qiáng)制指定。
2) Serial Old收集器(標(biāo)記-整理算法)
老年代單線程收集器,Serial收集器的老年代版本。
3) ParNew收集器(停止-復(fù)制算法)
新生代多線程收集器,其實(shí)就是Serial收集器的多線程版本,在多核CPU環(huán)境下有著比Serial更好的表現(xiàn)。
4) Parallel Scavenge收集器(停止-復(fù)制算法)
新生代并行的多線程收集器,追求高吞吐量,高效利用CPU。吞吐量一般為99%, 吞吐量= 用戶(hù)線程時(shí)間/(用戶(hù)線程時(shí)間+GC線程時(shí)間)。適合后臺(tái)應(yīng)用等對(duì)交互相應(yīng)要求不高的場(chǎng)景。是server級(jí)別默認(rèn)采用的GC方式,可用-XX:+UseParallelGC來(lái)強(qiáng)制指定,用-XX:ParallelGCThreads=4來(lái)指定線程數(shù)。
5) Parallel Old收集器(停止-復(fù)制算法)
老年代并行的多線程收集器,Parallel Scavenge收集器的老年代版本,并行收集器,吞吐量?jī)?yōu)先。
6) CMS(Concurrent Mark Sweep)收集器(標(biāo)記-清除算法)
CMS收集器是一種以獲取最短回收停頓時(shí)間為目標(biāo)的收集器,CMS收集器是基于“標(biāo)記--清除”(Mark-Sweep)算法實(shí)現(xiàn)的,整個(gè)過(guò)程分為四個(gè)步驟:
初始標(biāo)記: 標(biāo)記GC Roots能直接關(guān)聯(lián)到的對(duì)象,速度很快;
并發(fā)標(biāo)記: 進(jìn)行GC Roots Tracing的過(guò)程;
重新標(biāo)記: 修正并發(fā)標(biāo)記期間因用戶(hù)程序繼續(xù)運(yùn)作而導(dǎo)致標(biāo)記產(chǎn)生變動(dòng)的那一部分對(duì)象的標(biāo)記記錄,這個(gè)階段的停頓時(shí)間一般會(huì)比初始標(biāo)記階段稍長(zhǎng)一些,但比并發(fā)標(biāo)記時(shí)間短;
并發(fā)清除: 整個(gè)過(guò)程中耗時(shí)最長(zhǎng)的并發(fā)標(biāo)記和并發(fā)清除過(guò)程收集器線程都可以與用戶(hù)線程一起工作,所以,從總體上來(lái)說(shuō),CMS收集器的內(nèi)存回收過(guò)程是與用戶(hù)線程一起并發(fā)執(zhí)行的。
優(yōu)點(diǎn):并發(fā)收集、低停頓
缺點(diǎn):對(duì)CPU資源非常敏感、無(wú)法處理浮動(dòng)垃圾、產(chǎn)生大量空間碎片。
7) G1(Garbage First)收集器(標(biāo)記-整理算法)
G1是一款面向服務(wù)端應(yīng)用的垃圾收集器,是基于“標(biāo)記-整理”算法實(shí)現(xiàn)的,與其他GC收集器相比,G1具備如下特點(diǎn):
并行與并發(fā)
分代收集
空間整合
可預(yù)測(cè)性的停頓
G1運(yùn)作步驟:
初始標(biāo)記(stop the world事件,CPU停頓只處理垃圾)
并發(fā)標(biāo)記(與用戶(hù)線程并發(fā)執(zhí)行)
最終標(biāo)記(stop the world事件,CPU停頓處理垃圾)
篩選回收(stop the world事件,根據(jù)用戶(hù)期望的GC停頓時(shí)間回收)
3.4.5 垃圾收集結(jié)構(gòu)圖作者:郭曉利
來(lái)源:宜信技術(shù)學(xué)院
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/75547.html
摘要:本文是作者自己對(duì)中線程的狀態(tài)線程間協(xié)作相關(guān)使用的理解與總結(jié),不對(duì)之處,望指出,共勉。當(dāng)中的的數(shù)目而不是已占用的位置數(shù)大于集合番一文通版集合番一文通版垃圾回收機(jī)制講得很透徹,深入淺出。 一小時(shí)搞明白自定義注解 Annotation(注解)就是 Java 提供了一種元程序中的元素關(guān)聯(lián)任何信息和著任何元數(shù)據(jù)(metadata)的途徑和方法。Annotion(注解) 是一個(gè)接口,程序可以通過(guò)...
摘要:是目前的實(shí)驗(yàn)收集器。也是需要暫停程序一切的工作,然后多線程執(zhí)行垃圾回收。與最大的不同,它關(guān)注的是垃圾回收的吞吐量。這里的吞吐量指的是總時(shí)間與垃圾回收時(shí)間的比例。篩選回收,評(píng)估標(biāo)記垃圾,根據(jù)模式回收垃圾。 《對(duì)象搜索算法與回收算法》介紹了垃圾回收的基礎(chǔ)算法,相當(dāng)于垃圾回收的方法論。接下來(lái)就詳細(xì)看看垃圾回收的具體實(shí)現(xiàn)。 上文提到過(guò)現(xiàn)代的商用虛擬機(jī)的都是采用分代收集的,不同的區(qū)域用不同的收集...
垃圾回收(GC)是JVM的一大殺器,它使程序員可以更高效地專(zhuān)注于程序的開(kāi)發(fā)設(shè)計(jì),而不用過(guò)多地考慮對(duì)象的創(chuàng)建銷(xiāo)毀等操作。但是這并不是說(shuō)程序員不需要了解GC。GC只是Java編程中一項(xiàng)自動(dòng)化工具,任何一個(gè)工具都有它適用的范圍,當(dāng)超出它的范圍的時(shí)候,可能它將不是那么自動(dòng),而是需要人工去了解與適應(yīng)地適用。 擁有一定工作年限的程序員,在工作期間肯定會(huì)經(jīng)常碰到像內(nèi)存溢出、內(nèi)存泄露、高并發(fā)的場(chǎng)景。這時(shí)候在應(yīng)對(duì)這...
摘要:在退出時(shí)執(zhí)行必要的挽救措施。在這種情況下,一旦被提供,等待一個(gè)進(jìn)程終止指定的時(shí)間。如果進(jìn)程在該時(shí)間限制內(nèi)沒(méi)有終止,則通過(guò)發(fā)出或中的對(duì)等方強(qiáng)制終止進(jìn)程。所以有可能這是在中途執(zhí)行時(shí)發(fā)生的。 shutdownHook是一種特殊的結(jié)構(gòu),它允許開(kāi)發(fā)人員插入JVM關(guān)閉時(shí)執(zhí)行的一段代碼。這種情況在我們需要做特殊清理操作的情況下很有用 用途 在Jboss,Jetty等容器中都可以看到shutdown...
摘要:對(duì)象存不進(jìn)去,會(huì)又一次觸發(fā)垃圾回收。也就是說(shuō),它在進(jìn)行垃圾回收時(shí),必須暫停其他所有線程。我們來(lái)看一個(gè)名詞吞吐量。吞吐量運(yùn)行用戶(hù)代碼時(shí)間運(yùn)行用戶(hù)代碼時(shí)間垃圾收集時(shí)間。也就是說(shuō),收集器會(huì)嚴(yán)格控制吞吐量,至于這個(gè)吞吐量是多少,這個(gè)可以人為設(shè)置。 與其他語(yǔ)言相比,例如c/c++,我們都知道,java虛擬機(jī)對(duì)于程序中產(chǎn)生的垃圾,虛擬機(jī)是會(huì)自動(dòng)幫我們進(jìn)行清除管理的,而像c/c++這些語(yǔ)言平臺(tái)則需要...
閱讀 4319·2021-09-24 09:47
閱讀 1192·2021-09-03 10:33
閱讀 2077·2019-08-30 11:13
閱讀 1039·2019-08-30 10:49
閱讀 1762·2019-08-29 16:13
閱讀 2052·2019-08-29 11:28
閱讀 3102·2019-08-26 13:31
閱讀 3638·2019-08-23 17:14