網上有很多關于pos機面試技巧,聊聊 GC 機制的知識,也有很多人為大家解答關于pos機面試技巧的問題,今天pos機之家(m.afbey.com)為大家整理了關于這方面的知識,讓我們一起來看下吧!
本文目錄一覽:
1、pos機面試技巧
pos機面試技巧
前言
GC 中文直譯垃圾回收,是一種回收內存空間避免內存泄漏的機制。當 JVM 內存緊張,通過執(zhí)行 GC 有效回收內存,轉而分配給新對象從而實現(xiàn)內存的再利用。 JVM GC 機制雖然無需開發(fā)主動參與,減輕不少工作量,但是某些情況下,自動 GC 將會導致系統(tǒng)性能下降,響應變慢,所以這就需要我們提前了解掌握 GC 機制。當面對這種情況時,才能從容不迫的解決問題。另外 GC 機制也是 Java 面試高頻考題,了解掌握 GC 是一項必備技能。
學習 GC ,首先我們解決三個問題:
什么是垃圾在哪里回收垃圾怎么回收垃圾什么是垃圾我們先來看一段簡單的代碼。
上面代碼通過將字符串對象轉化成字節(jié)數(shù)組,然后寫入本地文件。方法一旦開始執(zhí)行,就將會在分配一定內存給新建的對象,然后將引用告訴了str, bytes 變量。等到方法執(zhí)行完畢,方法內部局部變量緊接將就會被銷毀。但是這樣僅僅銷毀了局部變量,卻沒有帶走內存上這些實際的對象。這類不再起作用,沒有被引用的對象,將其歸類為垃圾。
在偌大的內存上存活著無數(shù)對象,GC 之前需要準確將這些對象標記出來,分為存活對象與垃圾對象。這個過程一旦少標記,那就只能等待下次 GC標記,再回收,這樣將會影響 GC 效率。另外決不能錯標記,將正常存活對象標記為垃圾。一旦回收正常存活的對象,可能就會引起程序各種崩潰。
目前有兩種算法可以用來標記:
引用計數(shù)法可達性分析法引用計數(shù)法引用計數(shù)法通過在對象頭分配一個字段,用來存儲該對象引用計數(shù)。一旦該對象被其他對象引用,計數(shù)加 1。如果這個引用失效,計數(shù)減 1。當引用計數(shù)值為 0 時,代表這個對象已不再被引用,可以被回收。
如上圖所示,當 str 引用堆中對象時,計數(shù)值增加為 1。當 str 變?yōu)?null 時,既不再引用該對象,計數(shù)值減 1。此時該對象就可以被 GC 回收。
引用計數(shù)法只需要判斷計數(shù)值,所以實現(xiàn)比較簡單,這個過程也比較高效。但是存在一個很嚴重的問題,無法解決對象循環(huán)引用問題。
從上圖可以看到, a,b 不再引用堆中對象,導致計數(shù)減一。此時兩個對象內部還存在互相引用,計數(shù)值不為 0,此時 GC 沒辦法回收該對象。
可達性分析法這個算法首先需要按照規(guī)則查找當前活躍的引用,將其稱為 GC Roots。接著將 GC Roots 作為根節(jié)點出發(fā),遍歷對象引用關系圖,將可以遍歷(可達)的對象標記為存活,其余對象當做無用對象。
注意這里是是引用,而不是對象。
從上圖可以看到,綠色對象雖然存在循環(huán)引用,但是由于這些對象不能被 GC Roots 遍歷到,所以將會被回收。
可以被當做GC Roots 活躍引用包括但不限于以下引用:
方法中局部變量靜態(tài)變量,常量JNI handles….在哪里回收垃圾還記得剛開始接觸 Java 時,只知道堆棧,對象實例分配在堆中,方法中局部變量位于棧中。實際上 JVM 內存區(qū)域劃分更加細致,分為:
堆方法區(qū)虛擬機棧本地方法棧程序計數(shù)器如圖所示,我們將內存劃分為線程私有與線程共享的區(qū)域。方法區(qū)與堆都是線程共享的區(qū)域,這兩部分占用 JVM 大部分內存,剩下三個小弟將會跟線程綁定,隨著線程消亡,自動將會被 JVM 回收。
堆
堆應該是大家最熟悉的一塊區(qū)域,幾乎所有對象實例都將會在此出生,通常也是虛擬機上占用內存最大一塊區(qū)域,簡直就是 JVM 內存中的大哥大。堆內存內部也不是簡簡單單一塊而已,目前將會根據(jù)分代算法,將堆分代,不同對象位于不同區(qū)域。這一點我們下文再詳細了解。
方法區(qū)
方法區(qū)將會保存已被虛擬上加載的類信息、常量,靜態(tài)變量,字節(jié)碼等信息,堆上的對象正式通過方法區(qū)這些信息,才能正確創(chuàng)建出來。
棧
虛擬機棧棧由一系列棧幀組成,每個棧幀其實代表一個方法,棧幀中將會保存一個方法的局部變量表,方法出入口信息,操作棧等。每當調用一個方法,就將會把這個棧幀壓入棧中,執(zhí)行結束,出棧。
本地方法棧與虛擬機棧比較類似,最大區(qū)別在于,虛擬機棧執(zhí)行的 Java 方法,而本地方法棧將會用來執(zhí)行 Native 方法服務。下面方法就會在本地方法棧中執(zhí)行。
public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length);
程序計數(shù)器
程序計算器可以說是這幾塊區(qū)域占用最小的一部分,但是功能卻十分重要。Java 源代碼通過編譯變成字節(jié)碼,然后被 JVM 載入運行之后,將會變成一條條指令,而程序計數(shù)器的工作就是告訴當前線程下一條需要執(zhí)行指令。這樣即使發(fā)生了線程切換,等待恢復的時候,當前線程依然知道接下去要執(zhí)行的指令。
怎么回收目前主流 GC 算法主要分為三種:
標記-清除算法復制算法標記-整理算法標記-清除算法這是一個最為基礎也是最容易實現(xiàn)的算法,主要實現(xiàn)步驟分為兩步:標記,清除。
標記:通過上述 GC Roots 標記出可達對象。清除:清理未標記對象。ps:這個圖著實難畫啊。。。。
可以看到經過這個算法回收之后,雖然堆空間被清理出來,但是也產生很多空間碎片。這就會導致一個新對象根據(jù)堆剩余容量計算,看起來是可以分配,但是實際分配過程,由于沒有連續(xù)內存,導致虛擬機感知到內存不足,又不得不提前再次觸發(fā) GC。
可能這里你就會有疑惑,為什么對象需要分配一塊連續(xù)的內存?
這里引用一下 R 神 @RednaxelaFX 答案。
另外這個算法還有一個不足:標記與清除效率比較低。這就竟會導致 GC 占用時間過長,影響正常程序使用。
復制算法為了解決上述效率問題,誕生復制算法。這個算法將可用內存分為兩塊,每次只使用其中一塊,當這一塊內存使用完畢,觸發(fā) GC ,將會把存活的對象依次復制到另外一塊上,然后再把已使用過的內存一次性清理。
這個算法每次只需要操作一半內存,GC 回收之后也不存在任何空間碎片,新對象內存分配時只需要移動堆頂指針,按順序分配內存即可,實現(xiàn)簡單,運行高效。但是這個算法閑置一半內存空間,空間利用效率不高。
PS:復制算法以空間換時間,兩者不可兼得
另外對象存活率也會影響復制算法效率。如果對象大部分都是朝生夕死,只需要移動少量存活對象,就能騰出大部分空間。反而如果對象存活率高,這就需要進行較多的復制操作,回收之后也并沒有多余內存,這就可能導致頻繁觸發(fā) GC。
針對這種存活時間長的對象,就需要使用標記-整理算法。
標記-整理算法標記-整理算法可以說是標記-清除算法的改進版,改進了清除導致的空間碎片問題。這個算法分為兩步:
標記:也是通過 GC Roots 標記存活對象。整理:將存活對象往一端移動,按照內存地址一次排序,然后將末端邊界之外內存直接清理。雖然標記-整理算法解決了標記-清除算法空間碎片問題,也完整利用整個內存空間,但是這個算法問題效率并不高。相較于標記-清除算法,標記-整理算法多增加整理這一步,所以該算法效率還低于標記-清除算法。
分代收集算法從上面三種 GC 算法可以看到,并沒有一種空間與時間效率都是比較完美的算法,所以只能做的是綜合利用各種算法特點將其作用到不用的內存區(qū)域。
目前商業(yè)虛擬機根據(jù)對象存活周期不同劃分內存區(qū)域,一般分為新生代,老年代。新對象一般情況都會優(yōu)先分配在新生代,新生代對象若存活時間大于一定閾值之后,將會移到至老年代。新生代的對象都是短命鬼,老年代的對象都是長壽先生。
新生代每次 GC 之后都可以回收大批量對象,所以比較適合復制算法,只需要付出少量復制存活對象的成本。這里內存劃分并沒有按照 1:1 劃分,默認將會按照 8:1:1 劃分成 Eden 與兩塊 Survivor空間。每次使用 Eden 與一塊Survivor空間,這樣我們只是閑置 10% 內存空間。不過我們每次回收并不能保證存活對象小于 10%,在這種情況下就需要依靠老年代的內存分配擔保。當Survivor空間并不能保存剩余存活對象,就將這些對象通過分配擔保進制移動至老年代。
老年代中對象存活率將會特別高,且沒有額外空間進行分配擔保,所以并不適合復制算法,所以需要使用標記-清除或標記-整理算法。
隨便聊聊最近又到一年一次大考的時候,不得不又拿起周志明『深入 Java 虛擬機』重新學習。還記得第一次翻看這本書的時候,大半內容看不懂,看完也很快就忘了。然后過了一段時間,又重新拿起此書,這次比上次好,也已經能看小大半了。最近跟一些小伙伴聊天,發(fā)現(xiàn)他們都是看這本書學習 JVM ,不得不說這本書真是一本神書。最近『深入 Java 虛擬機』第三版即將上架開售,有需要的小伙伴可以考慮入手了。
好了 ,GC 機制就就總結到這里,下一篇我們來聊聊 JVM 常用 GC 回收器。
幫助鏈接GC Roots Java虛擬機詳解04—-GC算法和種類 深入 Java 虛擬機
以上就是關于pos機面試技巧,聊聊 GC 機制的知識,后面我們會繼續(xù)為大家整理關于pos機面試技巧的知識,希望能夠幫助到大家!
