1. 程式人生 > >Java相關知識點整理《一》

Java相關知識點整理《一》

1、JVM記憶體模型。

1.1.程式計數器。

當前執行緒所執行的位元組碼的行號指示器。

​​​​​​​1.2.Java虛擬機器棧。

執行緒私有,生命週期與執行緒相同,描述的是Java方法執行的記憶體模型。

​​​​​​​1.3.本地方法棧。

虛擬機器棧為虛擬機器執行Java方法(也就是位元組碼)服務,而本地方法棧則是為虛擬機器中使用到的Native方法服務。

1.4.Java堆。

Java堆是被所有執行緒共享的一塊記憶體區域,在虛擬機器啟動的時候建立。

1.5.方法區。

與堆一樣,各個執行緒共享的區域,用於儲存已被虛擬機器載入的類資訊、常量、靜態變數、即時編譯器(執行時常量池)編譯後的程式碼等資料。

2、類載入機制。

class檔案由類裝載器裝載後,在JVM中形成一份描述class結構的元資訊物件,通過元資訊物件可以獲知class的結構資訊;如建構函式、屬性和方法等。Java允許使用者藉由這個class相關的元資訊物件間接呼叫class物件的功能。

虛擬機器把描述類的資料從class檔案載入到記憶體,並對資料進行校驗、轉化解析和初始化,最終形成可被虛擬機器直接使用的Java型別,這就是類載入機制。

3、什麼是Java垃圾回收機制(GC)。

在系統執行過程中,會產生一些無用的物件,這些物件佔據著一定的記憶體,如果不對這些物件清理無用的記憶體,可能會導致記憶體耗盡,所以垃圾回收機制回收的是記憶體。同時GC回收的是堆區和方法區的記憶體。

4、垃圾回收演算法整理。

4.1.引用​​​​​​​計數器演算法。

是否有任一地方對物件進行了呼叫(物件是否已死)。

​​​​​​​4.2.可達性分析演算法。

選擇一個節點作為GC Roots,校驗從GC Roots是否可達當前物件(物件是否已死)。

​​​​​​​​​​​​​​4.3.標記-清除演算法。

先標記出待清除物件,再整體進行清除操作。

效率問題,容易產生大量不連續的記憶體碎片。

4.4.複製演算法。

將記憶體劃分為容量等大的兩塊,當一塊用完了,就把還存活著的物件複製到另一塊上,然後再把已使用過的記憶體空間一次性清理掉。

4.5.標記-整理演算法。

讓所有活著的物件都向一端移動,然後直接清理掉端過界以外的記憶體。

4.6.分代收集演算法。

分別對新生代和老年代的記憶體進行回收。

5、各垃圾收集器的優缺點。

5.1.Serial收集器。

優點:簡單高效,對於限定單個CPU來說,Serial收集器沒有現成互動的開銷,可專心做垃圾收集以獲得最高的單執行緒收集效率。

缺點:單執行緒收集器,在進行垃圾收集時,必須停頓其他所有執行緒。

5.2.ParNew收集器。

Serial收集器的多執行緒版本。

5.3.Parallel Scavenge收集器。

吞吐量優先收集器:使Jvm達到一個可控的吞吐量。

吞吐量=執行使用者程式碼時間/(執行使用者程式碼時間+垃圾收集時間)

5.4.Serial Old收集器。

Serial收集器的老年代版本,使用標記—整理演算法。

5.5.Paraller Old收集器。

使用多執行緒和標記—整理演算法收集。

5.6.CMS收集器。

最短回收停頓,採用標記—清除演算法。

優點:併發收集,低停頓。

缺點:

(a)、CPU資源敏感。

(b)、無法處理浮動垃圾,即無法處理在垃圾收集過程中產生的新垃圾。

(c)、容易產生空間碎片。

5.7.G1收集器。

併發與並行、分代收集、空間整合、可預測的停頓

6、ThreadLocal執行緒區域性變數。

所謂執行緒區域性變數,就是僅僅能被本執行緒訪問,不能線上程之間共享的變數。

synchronized用於縣城之間的資料共享(使變數或者程式碼塊在某一時刻只能被一個執行緒訪問),是一種延長訪問時間來換取執行緒安全的策略。

ThreadLocal用於執行緒間的資料隔離(為每一個執行緒都提供了變數的副本),是一種以空間來換取執行緒安全的策略。

7、Java執行緒池ThreadExecutor。

執行緒池:一種多執行緒的處理形式,處理過程中將任務新增到佇列,然後在建立執行緒後自動啟動這些任務。

執行緒池執行緒都是後臺執行緒,每個執行緒都是用預設的堆疊大小,以預設的優先順序執行,並處於多執行緒單元中。

corePoolSize:核心執行緒池大小

maximumPoolSize:最大執行緒池大小

workQueue:阻塞任務佇列

threadFactory:新建執行緒工廠

keepAliveTime:執行緒池中超過corePoolSize數目的空閒執行緒最大存活時間;可以allowCoreThreadTimeOut(true)使核心執行緒有效時間。

TimeUnit:keepAliveTime的單位。

注意:

(a)、當執行緒池小於corePoolSize時,新提交任務將建立一個新執行緒執行任務,即使此時執行緒池中存在空閒執行緒。

(b)、當執行緒池達到corePoolSize時,新提交的任務被放入workQueue中,等待執行緒池中任務排程執行。

(c)、當workQueue已滿,且maximumPoolSize>corePoolSize時,新提交的任務會建立新執行緒執行任務。

(d)、當提交任務超過maximumPoolSize時,新提交的任務由RejectedExecutionHandler處理。

(e)、當執行緒池中超過corePoolSize,空閒時間達到keepAliveTime時,關閉空閒執行緒。

(f)、當設定allowCoreThreadTimeOut(true)時,執行緒池中corePoolSize執行緒空閒時間達到keepAliveTime也將關閉。

8、Lock關鍵字。

Synchronized關鍵字是Java語言內建關鍵字,Lock是一個類,通過這個類可以實現同步訪問。

Synchronized不需要使用者手動去釋放鎖,當Synchronized方法或者程式碼塊執行完之後,系統會自動讓執行緒釋放對鎖的佔用;而Lock則必須要使用者去手動釋放鎖,如果沒有主動釋放鎖,就有可能出現死鎖現象。

一般來說,使用Lock必須在try{}catch{}finally{}中執行,並且將釋放鎖的操作放在finally塊中執行,以保證鎖一定會被釋放,防止死鎖發生。

9、Volatile關鍵字。

保證不同執行緒對這個變數進行的操作時的可見性,所有執行緒都能看到共享記憶體的最新狀態。

Java通過以下幾種原子性操作完成工作記憶體和主記憶體的互動:

(a)、lock:作用於主記憶體,把變數標識為執行緒獨佔狀態。

(b)、unlock:解除獨佔狀態。

(c)、read:作用主記憶體,把一個變數的值從主記憶體傳輸到執行緒的工作記憶體。

(d)、load:作用工作記憶體,把read操作傳過來的變數值放入工作記憶體的變數副本中。

(e)、use:作用工作記憶體,把工作記憶體當中的一個變數值傳給執行引擎。

(f)、assign:作用工作記憶體,把一個從執行引擎接收到的值賦給工作記憶體的變數。

(g)、store:作用於工作記憶體的變數,把工作記憶體的一個變數值傳送到主記憶體中。

(h)、write:作用於主記憶體的變數,把store操作傳來的變數放入主記憶體的變數中。

Volatitle是如何保持記憶體的可見性?

read、load、use動作必須連續出現。

assign、store、write動作必須連續出現。

使用volatitle關鍵字能夠保證:

每次讀前必須從主記憶體重新整理最新的值。

每次寫入後必須立即同步到主記憶體中。

總結:volatitle關鍵字修飾的變數看到的隨時是自己的最新值。