偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

面試的時候按照這個套路回答 Java GC 的相關問題一定能過!

開發(fā) 后端
剛好前幾天一個小伙伴在微信上問阿粉,說是面試一家公司被問到 Java GC 相關的東西,雖然平時也有準備,但是回答起來總是零零散散,感覺沒有邏輯。其實阿粉也能理解,現(xiàn)在面試都是一種問答模式,一個隨便問問,一個死記硬背,很多時候面試前準備的好好的一到面試的時候可能緊張就給忘了,事后感覺自己表現(xiàn)的不好。

 Hello 大家好,我是鴨血粉絲,2020 注定是一個不平凡的一年,很多小伙伴在后臺和星球留言都說今年的工作不好找,也有應屆生小伙伴給阿粉發(fā)消息問阿粉所在的公司今年是否招應屆生,阿粉也只能幫小伙伴問問 HR,但是阿粉也做不了主。

剛好前幾天一個小伙伴在微信上問阿粉,說是面試一家公司被問到 Java GC 相關的東西,雖然平時也有準備,但是回答起來總是零零散散,感覺沒有邏輯。其實阿粉也能理解,現(xiàn)在面試都是一種問答模式,一個隨便問問,一個死記硬背,很多時候面試前準備的好好的一到面試的時候可能緊張就給忘了,事后感覺自己表現(xiàn)的不好。

這篇文章給大家舉個例子,在遇到一個問題或者知識點的時候要怎么去理解和學習。

Java GC

目標

遇到一個問題或者一個知識點,我們要理解和明白是要解決什么問題的。說到 Java GC 那這個 GC 的目的是什么呢?很顯然是回收內存,因為內存是有限的,隨著程序中創(chuàng)建的對象越來越多,如果進行回收就會導致內存越來越大,最后程序就會出現(xiàn)異常。既然目的是為了回收內存,那么新的問題來了,哪些對象可以被回收呢?什么時候進行回收呢?怎么回收呢?

哪些對象可以被回收

簡單來說就是無用的對象可以被回收,那么換句話說,如果定義一個對象是無用的呢?這里主要有兩種方法,一個叫引用計數(shù)法,一個叫可達性分析法。

引用計數(shù)

引用計數(shù)說的是如果一個對象被別的對象進行了一次引用,那么該對象會有一個引用計數(shù)器,這個計數(shù)器就會加一;如果被釋放一下,引用計數(shù)器就會減一。當引用計數(shù)器的計數(shù)為 0 的時候就表示這個對象是無用的,此時就可以對這樣對象進行回收了。表面上看好像挺合理的,實現(xiàn)起來也很方便,但是仔細一想就會發(fā)現(xiàn)有問題。既循環(huán)引用的問題,比如對象 A 引用了對象 B,但是對象 B 當中也引用了對象 A,那么這個時候對象 A 和對象 B 的引用計數(shù)器的計數(shù)都不會是 0,但是這兩個對象都沒有被其他對象引用,理論上來說這兩個對象都是可以被回收的。

從上面看到,這種方案是有問題的會導致內存泄露。隨之而來的就出現(xiàn)了另一種方案,可就是可達性分析。

可達性分析

可達性分析說的是從 GCRoots 的點作為起點,向下搜索,當找不到任何引用鏈的時候表示該對象為垃圾對象。那么哪些對象可以被認為是 Roots 節(jié)點呢?有 Java 棧中的對象,方法區(qū)的靜態(tài)屬性和常量以及本地方法棧中的對象。從這幾種對象依次向下搜索,如果沒有能達到 Roots 節(jié)點的對象就是垃圾對象,就說明可以被回收。

如下圖所有,對象 A,B,C都能找到與 Roots 節(jié)點的聯(lián)系,但是對象 D,E,F(xiàn) 三個并不能找到與 Roots 節(jié)點的聯(lián)系,也就是不可達,所以 DEF 這三個對象就是垃圾對象。

什么時候回收

上面的兩種方案解決了哪些對象能被回收,那么下個問題,就是什么時候進行垃圾回收呢?在排除人為調用的時候,垃圾回收都是發(fā)生在為新生對象進行內存分配的時候,這個時候如果內存空間不足就會觸發(fā) GC 進行垃圾回收。

怎么回收

上面我們知道了哪些對象可以被回收,也知道我們應該什么時候進行回收,那下面要解決的就是如何進行垃圾回收了。垃圾回收根據(jù)實現(xiàn)的方式不同有多種不同的算法實現(xiàn)。比如有標記清除算法,復制算法,標記整理算法,分代回收算法,下面簡單介紹一下,想深入了解的可以自行去研究一下。

標記清除算法

標記清除算法很好理解,主要就是執(zhí)行兩個動作,一個是標記,另一個是對進行標記的對象內存進行清除回收。這個算法有個問題就是會出現(xiàn)內存碎片化嚴重。如下圖所示:

從上圖中可以看到,在進行內存回收后出現(xiàn)了嚴重的內存碎片化,這就導致在分配某些大對象的時候仍然會出現(xiàn)內存不夠的情況,但是總體內存確是夠的。

復制算法

復制算法的實現(xiàn)方式比較簡潔明了,就是霸道的把內存分成兩部分,在平時使用的時候只用其中的固定一份,在當需要進行 GC 的時候,把存活的對象復制到另一部分中,然后將已經(jīng)使用的內存全部清理掉。如下圖:

從上圖可以看到解決了標記清除的內存碎片化問題,但是很明顯復制算法有另一個問題,那就是內存的使用率大大下降,能使用的內存只有原來的一半了。

標記整理算法

既然標記清除和復制算法各有優(yōu)缺點,那自然的我們就想到是否可以把這兩種算法結合起來,于是就出現(xiàn)了標記整理算法。標記階段是標記清除算法一樣,先標記出需要回收的部分,不過清除階段不是直接清除,而是把存活的對象往內存的一端進行移動,然后清除剩下的部分。如下圖:

標記整理的算法雖然可以解決上面兩個算法的一些問題,但是還是需要先進行標記,然后進行移動,整個效率還是偏低的。

分代回收算法

分代回收算法是目前使用較多的一種算法,這個不是一個新的算法,只是將內存進行的劃分,不同區(qū)域的內存使用不同的算法。根據(jù)對象的存活時間將內存的劃分為新生代和老年代,其中新生代包含 Eden 區(qū)和 S0,S1。在新生代中使用是復制算法,在進行對象內存分配的時候只會使用 Eden 和 S0 區(qū),當發(fā)生 GC 的時候,會將存活的對象復制到 S1 區(qū),然后循環(huán)往復進行復制。當某個對象在進行了 15 次GC 后依舊存活,那這個對象就會進入老年代。老年代因為每次回收的對象都會比較少,因此使用的是標記整理算法。

垃圾回收器

講完了垃圾回收算法,我們再看下垃圾回收器,每一種垃圾回收器都是不同時代的不同產(chǎn)物,都有其獨特性。

  • Serial 垃圾收集器(單線程、復制算法)
  • ParNew垃圾收集器(Serial+多線程)
  • Parallel Scavenge 收集器(多線程復制算法、高效)
  • SerialOld收集器(單線程標記整理算法)
  • ParallelOld收集器(多線程標記整理算法)
  • CMS收集器(多線程標記清除算法)
  • G1收集器

各個垃圾收集器的配合使用情況可以參考下圖,個人覺得對這么多的收集器沒有必要全部精通,可以注重關注一下 CMS 和 G1 就可以了。感興趣的小伙伴可以自己的研究一下。

 

責任編輯:武曉燕 來源: Java極客技術
相關推薦

2016-01-11 11:50:39

JavaScript閉包面試題

2022-08-09 20:48:24

算力網(wǎng)絡運營商

2020-09-08 14:05:06

Redis數(shù)據(jù)庫緩存

2022-08-18 08:08:56

TCP連通ECMP

2013-05-14 10:41:16

Palo AltoNGFWUTM

2022-07-20 07:45:15

多線程程序性能

2019-09-16 09:03:11

數(shù)據(jù)庫SQLMySQL

2015-08-05 10:40:02

大公司技術程序員

2015-08-05 09:26:55

技術大公司

2017-08-14 16:12:56

面試套路原則

2023-01-10 11:29:34

2023-09-14 10:55:16

2015-08-05 09:15:31

bat學習

2017-01-19 17:57:47

大數(shù)據(jù)

2020-01-20 14:27:57

程序員數(shù)據(jù)庫電子商務

2023-05-16 14:07:52

AI自然語言

2018-11-27 09:45:54

2015-01-13 10:21:00

2020-10-27 10:58:07

Linux內核操作系統(tǒng)
點贊
收藏

51CTO技術棧公眾號