可以說,學姐給我的這份檔案真的把我的知識查漏補缺,面試問到了好多,值得收藏,
并發編程
一.Executor
為什么使用執行緒池:手動創建執行緒耗費性能,不利于管理,
首先創建執行緒池有兩種方式:使用Executors工廠來創建ThreadPoolExecutor這類自定義執行緒池,
1. 使用Executors工廠來創建
Executors是一個類,用來創建執行緒池,常用的有四種執行緒池
1.newFixedThreadPool 創建一個可重復固定的執行緒數的執行緒池
2.newCachedThreadPool 創建一個可快取的執行緒池,呼叫execute將重復用以前構造的執行緒(如果當前執行緒可用),如果沒有可用執行緒則創建新的執行緒并加入到池中,終止并從快取中移除那些已有60s未被使用的執行緒,
3.newSingleThreadExecutor創建一個單執行緒化的執行緒池,它只會用唯一的作業執行緒來執行任務,保證所有任務按照指定順序(FIFO, LIFO, 優先級)執行
4. newScheduledThreadPool 創建一個支持定時及周期性的任務執行的執行緒池,多數情況下可用來替代Timer類,
使用示例:

2. 使用ThreadPoolExecutor這個類自定義創建執行緒池


二.ThreadLocal


三.中斷執行緒
1.執行緒執行完畢會自動結束
2.在執行緒處于阻塞,期限等待火無期限等待時,呼叫執行緒的interrupt()會拋出interruptedException例外從而提前終止執行緒
3.若沒有處于阻塞狀態,呼叫interrupte()將執行緒標記為中斷,此時在呼叫interrupted()判斷執行緒是否處于中斷狀態,來提前終止執行緒,
4.執行緒池呼叫shutdown()等待所有執行緒執行完畢之后關閉
三.Volatile關鍵字的理解
兩層語意:1.保證不同執行緒對該變數的記憶體可見線
2.禁止進行指令重排序
記憶體語意:
讀這個變數的時候,JMM會把本地記憶體中的變數設定為無效,從主記憶體中取;
寫這個變數的時候,JMM會把本地記憶體變數重繪到主記憶體當中
實作:添加Volatile關鍵字會在匯編代碼中多處一個kock前指令,也就是記憶體屏障
四.Synchronized關鍵字
(1)synchronized是Java中的關鍵字,是一種同步鎖,它修飾的物件有以下幾種:
1. 修飾一個代碼塊,被修飾的代碼塊稱為同步陳述句塊,其作用的范圍是大括號{}括起來的代碼,作用的物件是呼叫這個代碼塊的物件;
2. 修飾一個方法,被修飾的方法稱為同步方法,其作用的范圍是整個方法,作用的物件是呼叫這個方法的物件;
3. 修飾一個靜態的方法,其作用的范圍是整個靜態方法,作用的物件是這個類的所有物件;
4. 修飾一個類,其作用的范圍是synchronized后面括號括起來的部分,作用主的物件是這個類的所有物件,
(2)Synchronized的作用主要有三個:(1)確保執行緒互斥的訪問同步代碼(2)保證共享變數的修改能夠及時可見(3)有效解決重排序問題,
(3)Synchronized 原理
在編譯的位元組碼中加入了兩條指令來進行代碼的同步,
monitorenter :
每個物件有一個監視器鎖(monitor),當monitor被占用時就會處于鎖定狀態,執行緒執行monitorenter指令時嘗試獲取monitor的所有權,程序如下:
1.如果monitor的進入數為0,則該執行緒進入monitor,然后將進入數設定為1,該執行緒即為monitor的所有者,
2.如果執行緒已經占有該monitor,只是重新進入,則進入monitor的進入數加1.
3.如果其他執行緒已經占用了monitor,則該執行緒進入阻塞狀態,直到monitor的進入數為0,再重新嘗試獲取monitor的所有權,
monitorexit:
執行monitorexit的執行緒必須是objectref所對應的monitor的所有者,
指令執行時,monitor的進入數減1,如果減1后進入數為0,那執行緒退出monitor,不再是這個monitor的所有者,其他被這個monitor阻塞的執行緒可以嘗試去獲取這個 monitor 的所有權,
通過這兩段描述,我們應該能很清楚的看出Synchronized的實作原理,Synchronized的語意底層是通過一個monitor的物件來完成,其實wait/notify等方法也依賴于monitor物件,這就是為什么只有在同步的塊或者方法中才能呼叫wait/notify等方法,否則會拋出java.lang.IllegalMonitorStateException的例外的原因,
(4)Synchronized的優化
(4)synchronized與Lock的區別
lock是一個類,主要有以下幾個方法:
lock():獲取鎖,如果鎖被暫用則一直等待
unlock():釋放鎖
tryLock(): 注意回傳型別是boolean,如果獲取鎖的時候鎖被占用就回傳false,否則回傳true
tryLock(long time, TimeUnit unit):比起tryLock()就是給了一個時間期限,保證等待引數時間

(1)Lock的加鎖和解鎖都是由java代碼實作的,而synchronize的加鎖和解鎖的程序是由JVM管理的,
(2)synchronized能鎖住類、方法和代碼塊,而Lock是塊范圍內的,
(3)Lock能提高多個執行緒讀操作的效率;
(4)Lock:Lock實作和synchronized不一樣,后者是一種悲觀鎖,它膽子很小,它很怕有人和它搶吃的,所以它每次吃東西前都把自己關起來,而Lock底層其實是CAS樂觀鎖的體現,它無所謂,別人搶了它吃的,它重新去拿吃的就好啦,所以它很樂觀,如果面試問起,你就說底層主要靠volatile和CAS操作實作的,
五.CAS機制
Compare And Swap
CAS操作是一個原子操作,由一條CPU指令完成,使用了3個基本運算元,記憶體地址V,舊的預期值A ,要修改的新值B
需要更新一個變數的時候,只有當記憶體地址V中的值和預期值A相等的時候才會修改為新值B ,如果失敗則自旋,重新嘗試
問題:
1.ABA 解決辦法,加一個版本號,只有當版本號和預期值都符合的時候才修改
2.不能保證代碼塊的原子性,CAS機制知識保證一個變數的原子操作
五.JMM的理解

JMM的核心是找到一個平衡點,在保證記憶體可見性的前提下,盡量的放松對編譯器和處理器重排序的限制,
可能會產生快取一致性的問題:
1.總線鎖定
2.快取一致性協議
三大特性:原子性,可見性,有序性
六.JVM的鎖優化
1.自旋鎖和自適應自旋鎖
執行緒掛起和恢復都需要很大的性能開銷,很多共享資料的鎖定狀態只持續很短的時間,為這段時間掛起恢復不值得,所以可以讓現場進入一個自旋狀態,但仍占用cpu的時間,默認是10次,超過10次則采用傳統的方式掛起執行緒,自適應自旋鎖會根據上次在這個鎖上自旋的時間調整自選次數
2.鎖消除
檢測到對區域變數加鎖,會自動將鎖消除,如在一個方法里面有sb = s1 + s2 + s3以前會轉化為StringBuffer(執行緒安全,有加鎖)的append操作,優化之后會轉換成StringBuilder的sppend操作
3.鎖粗化
對一個物件反復加鎖解鎖,如上述的append方法,編譯器會優化,只在最外層加一個鎖
4.輕量級鎖
物件有一個物件頭,物件頭分兩部磁區域,一部分存盤子樹的hashcode,GC分代年齡,鎖標志位等,官方成為mark word,另一部分用于存盤指向方法區物件型別的指標;
輕量級鎖的執行程序是代碼進入同步塊的時候,如果當前物件沒有被鎖定(鎖標志為是01)則先在執行緒的堆疊幀中建立一個鎖記錄空間(lock record)將物件的mark word拷貝過來,然后利用cas操作嘗試將物件的markword更新為指向lock record,如果成功則當前執行緒擁有該物件鎖,并且將鎖標志位從01改為00,如果更新失敗則會檢查當前物件markword是否指向當前執行緒的堆疊幀,如果是則直接進入同步塊執行否則說明當前的物件鎖已經被其他執行緒占有,如果有兩條以上的執行緒競爭這個鎖,那就會膨脹成重量級鎖,鎖標志為變成10;
5.偏向鎖
鎖物件第一次被執行緒獲取的時候,會將當前的鎖標志設定為偏向鎖01狀態,并使用cas操作將當前執行緒的id記錄在markword當中,如果成功那么在以后的操作當中不需進行任何操作就可以進入同步代碼塊,當有另外一個執行緒獲取當前鎖的時候,偏向模式就宣告結束,撤銷偏向鎖之后恢復到未鎖定或者輕量級鎖狀態
JAVA基礎
String
1.string s1 = “aaa” 與 String s1 = new String(aaa);
前者會在Stringpool中創建一個物件,如果Stringpool中已經有了,則直接參考
后者會在Stringpool和堆中分別創建一個物件,如果StringPool中已經有了則只創建一個物件
2.呼叫s1.integer()方法,可以將字串放入StringPool中,如果已經存在則直接回傳這個物件
繼承
1.幾種修飾符的訪問權限范圍

2. == equals hashcode的關系
1.==是比較兩個物件的地址是否相等
2.equals默認和 == 一樣也是比較地址,也可以根據自己的需求來重寫什么叫做相等
3.hashcode 是根據物件的地址來回傳一串int型數字,如果物件不一樣的話回傳的值也不一樣
3.為什么重寫equals的同時也要重寫hashcode
首先必須滿足如果equals相同,那么hashcode也必須相同,如果hashcode不相同,那么equals必須不相同的原則,否則會導致該類無法與基于散列值的集合類(hashmap , hashset ,hashtable)結合正常運行
因為對于這些集合在進行重復性判斷時,是先用hashcode判斷,如果相同在用equals判斷
4.hash沖突的解決方法
1.開放地址法(線性探測法,二次探測法)
2.在散列函式法
3.鏈地址法
5.hashtable與hashmap的區別
1.hashmap執行緒不安全,hashtable執行緒安全
2.hashmap最多允許一個鍵為null,而hashtable不允許
3.hashtable中默認的hash陣列大小為11,增加的方式是old*2+1,而hashmap默認是16,肯定是2的指數
4.計算hash的方法不一樣,hashtable是直接用hashcode,而hashmap使用了key的高16位和低16位做異或運算
Linkedhashmap繼承于hashmap,可以按順序讀取,底層使用的是雙向鏈表
TreeMap實作了sortmap介面,可以對元素進行排序,底層使用的紅黑樹
7.java BIO NIO AIO 序列化
位元組操作:使用inputStream和outPutSream實作,位元組是傳輸和存盤的最小單位
字符操作:inputStreamReader:將位元組流解碼成字符流
OutPutStramWriter:將字符流編碼成位元組流
物件操作:序列化就是將物件轉換成位元組序列,方便存盤和運輸,兩個用途:
1.把物件的位元組序列永久地保存到硬碟中,通常存放在一個檔案里
2.在網路上傳送物件的位元組序列
在很多應用中,需要對某些物件進行序列化,讓他們離開記憶體空間,入住到物理磁盤方便長期保存,比如session物件,當有大量用戶并發訪問的時候可能會出現10萬個session物件,記憶體吃不消,此時就需要將這些session先序列化到硬碟中,等要用的時候在把物件還原到記憶體中,
當兩個行程在進行遠程通信的時候,彼此可以發送各種型別的資料,無論是何種型別的資料,都會以二進制的序列在網路上傳送,發送方需要把這個java物件轉換成位元組序列,才能在網路上傳送;接收方則需要把位元組序列恢復成java物件,
Io與NIO的區別:
1.NIO是非阻塞的
2.NIO是面向緩沖區的,IO是面向流的
AIO:異步非阻塞
8.static關鍵字的作用
一.修飾變數:
1.靜態變數在類加載的時候被創建并初始化,只被創建一次(類加載只進行一次),可以修改
2.靜態變數屬于整個類而不屬于某個物件,
二.修飾方法
1.可以通過類名來訪問,不需要創建物件來訪問,可以用來實作單例模式
2.靜態方法只能呼叫靜態方法和靜態變數
三.修飾靜態代碼塊
在類加載的時候執行,且只執行一次
9.單例模式
實作:

1.為什么要用判斷雙重:
因為可能有兩個執行緒都執行完了第一個if陳述句,如果沒有第二重判斷,那么當其中有個執行緒執行完synchronized里面的陳述句之后,另外一個執行緒跟著也會執行,這樣就達不到單例模式的效果
2.第一重判斷去掉也可以實作,為什么不去掉
這個設計性能問題,因為
參考:https://qinjiangbo.com/mechanism-of-double-locking-check.html
10.this與super關鍵字
9.java中的多型
分為兩種:
1.編譯時多型:體現在多載(方法名相同而引數不同),在編譯時期就根據傳入的引數確定好呼叫哪個方法;
2.運行時多型:體現在方法的重寫,在運行時期判斷參考型別的實際型別根據實際的型別呼叫其相應的方法;
當父類物件參考變數參考子類物件時,被參考物件的型別決定了呼叫誰的成員方法,參考變數型別決定可呼叫的方法,如果子類中沒有覆寫該方法,那么會去父類中尋找,
參考鏈接:https://www.runoob.com/w3cnote/java-polymorphism.html
10.介面類和抽象類的異同
區別:
1.抽象類可以有非抽象方法,但介面只能有抽象方法
2.介面中的成員變數默認修飾為public static final(高度抽象的模版,所以這些都是提取出來的不變特征),方法默認修飾為public abstract,抽象類中的成員變數可以被不同的修飾符來修飾
3.類可以實作多個介面但只能繼承一個抽象類
相同:
1.不能被實體化
2.派生類都必須實作未實作的方法
11.instanceof
用來判斷一個物件是否是一個類的實體

12.各種排序演算法復雜度及穩定性

1.java底層如何實作排序的
Java中Arrays.sort使用了兩種排序方法,快速排序和優化歸并排序,
快速排序主要針對基本的資料型別(int short long)排序,而歸并排序用于物件型別的排序
如果資料量小于60會使用插入排序,插入排序是穩定的
13.java中的堆和堆疊
堆疊:主要用于存盤區域變數和物件的參考變數,每個執行緒都有一個獨立的堆疊空間,所以執行緒之間是不共享資料的;
堆疊的特點是存取速度快,但所存資料的大小和生存期必須是確定的(編譯后就已經確定大小)
堆:堆中主要存盤實體化的物件和陣列,執行緒共享,堆的優勢是可以動態的分配記憶體大小,生存期也不必事先告訴編譯器,但缺點是存取速度較慢
Linux基本面試題:
Ls:用于顯示指定作業目錄下的類容,不會列出詳細資訊
Ll:會列出當前檔案目錄的詳細資訊,含有時間,權限,大小等
Cd:用于切換到目標目錄
Mkdir:用于簡歷當前目錄的子目錄
rm-r 洗掉的檔案或者目錄,需確認
rm –rf同上但無需確認
cp:復制檔案 若復制目錄則必須加上-r
資料庫MySQL
一.索引
1.B樹,B+樹,以及兩者的區別
B樹是一種多路平衡查找樹,其每一個節點都存盤Key和data
B+樹是B樹的一個變種,葉子節點存盤data,非葉子節點只存盤key,B+樹的葉子節點增加了順序訪問指標,每一個葉子節點都可以訪問到他的下一個葉子節點
區別:
1.B+樹種只有葉子節點會帶有全部資訊,非葉子節點只起到索引的作用,二B樹的所有節點都帶有全部資訊,B+樹的每一層節點都會再次出現在下一層節點上
2.B+樹種所有葉子節點都是通過指標連在一起,B樹則沒有
2.索引的優點和缺點
優點:可以加大檢索速度
缺點:創建和維護索引需要耗費時間
3.Mysql為什么選擇B+樹
Mysql資料本質上是放在外部存盤的,B+樹是為了加快讀取速度二設計的一種資料結構
1.可以減少i/o次數,只有葉子節點才存盤資料,非葉子節點存盤索引,這樣一次讀取到記憶體的關鍵字增多,相對i/o次數也就減少(根據區別一)
2.能夠提供穩定高效的范圍掃描,因為所有的葉子節點都互相連接(根據區別二)
4.索引越多越好嗎?
索引可以提高select的效率,但是也降低了insert和updata的效率,因為插入和更新的時候可能會重建索引,索引怎么建索引要慎重考慮,
5.索引分類
1.B+樹索引:以b+樹作為資料結構的索引
2.hash索引:能以O(1)的時間復雜度查找,但失去了有序性,innodb有一個自適應哈希索引,當這個索引值被頻繁使用時會在b+樹上創建一個哈希索引
3.全文索引:用于查找文本的關鍵詞,中文需要由中文分詞插件
二. MySQL優化
一.MySQL的優化,主要分為索引的的優化,sql陳述句的優化,表的優化,同時可以使用快取增加效率
1.索引的優化
只要列中含有null,最好不要再此列設定索引
對于經常在where陳述句中使用的列,最好設定一個索引
對于like陳述句,以%或者-開頭的不會使用索引,以%結尾會使用索引
二.sql陳述句的優化
查詢優化要盡量避免全表掃描
查詢時能不用*就不用*,盡量寫欄位名
三. MySQL常問問題
1.資料庫如何應對大規模的寫入和讀取
(1)使用NoSQL,通過降低資料的安全性,減少對事物的支持,減少復雜查詢的支持來獲取性能的提升;但有些場合NoSQL無法滿足要求
(2)分庫分表:
水平切分:不修改資料庫的表結構,通過對表中的資料拆分而達到分片的目的,一般水平切分在查詢的時候可能會用到union操作(多個結果并)
可以根據hash或者日期來進行分表
垂直切分:修改表結構,按照訪問的差異將某些列拆分出去,一般查詢資料的時候可能會用到join操作;把常用的欄位放在一個表中,不常用的放在一個表中;把欄位比較大的比如text欄位拆出來放在一個表中,
分庫:分表能夠解決資料量過大帶來的查詢效率下降問題,但是卻無法給資料庫的并發處理能力帶來質的提升;分庫可以對關鍵字取模的方式來對資料訪問進行路由;
(3)讀寫分離:
讀寫分離是在主服務器上修改資料,資料也會同步到從服務器上,從服務器只能提供讀取,不能寫入,實作備份的同時也實作了資料庫的性能優化

如何保證資料一致性:
(1)主節點
保證事務每次提交之后,要確保binlog都能重繪到磁盤中,只要有了binlog,innoDB就有方法恢復資料,不至于導致主從復制的資料丟失
(2)從節點
開啟 relay log 自動修復機制,發生 crash 時,會自動判斷哪些 relay log 需要重新從master 上抓取回來再次應用,以此避免部分資料丟失的可能性,
2.資料庫事務及其隔離級別
事務的特性:ACID
事務在并發的時候,隔離性很難保證主要可能出現下面這些問題:
臟讀:一個事務讀了另外一個事務未提交的資料,如果另一個事務回滾則會發生臟讀
不可重復讀:一個事務前后讀取同一行資料,如果在這個程序中有其他事務修改了此資料則會發生不可重復讀
幻讀:一個事務前后讀取范圍的時候
事務隔離級別:

MySQL實作事務是基于undo/redo日志實作的:
undo日志記錄修改前的狀態,ROLLBACK基于UNDO日志實作;
REDO日志記錄修改后的狀態,事務的持久性基于REDO日志實作
兩種解決臟讀、不可重復讀、幻讀的方案:
MVCC(性能較高,但讀的可能是歷史版本)
1.版本鏈:對于每一行的資料,在undo日志中,總會記錄每個版本記錄以及對應的事務id,
2.readView:
核心問題:當前版本鏈中哪個版本對當前事務可見
Readview包含的內容:{當前活躍的事務id,下一個應該分配的事務id,當前自己的事務id},根據當前讀的版本事務id和這個readview對比,如果是活躍的或者大于下一個應該分配的事務id則說明當前版本對此事務不可見,應該前讀一個版本,依次類推直到找到可見的版本
提交讀:每次讀取資料前都會生成一個readview
可重復讀:在第一次讀取時句時生成一個readview
鎖(性能不高,但讀的是最新版本):

MyISAM和innoDB的區別
1.innodb支持行鎖,myisam不支持行鎖
2.innodb支持事務,myisam不支持事務
3.innodb支持回滾和安全回復,myisam不支持
4.innodb的索引就是資料,myisam的索引只存盤了主鍵和行號,還需要根據行號去查找相應的記錄
5.innodb更適合寫密集的表,myisam更適合讀密集的表
計算機網路
1.tcp和udp的區別:
Udp:無連接,盡最大可能交付,沒有擁塞控制流量控制
Tcp:面向連接,可靠交付,有擁塞控制和流量控制
2.輸入一條url,整個程序:
1.DNS決議,獲取ip地址(本機,本地域名服務器,根域名服務器,頂級域名服務器,權限域名服務器)
2.建立TCP連接
3.瀏覽器發出http請求
4.服務器進行回應
5.TCP連接釋放
6.瀏覽器渲染
3.為什么是三次握手,四次揮手
三次握手:防止之前滯留的連接請求再次到達服務端
四次揮手:因為tcp是全雙工模式,客戶端停止發送請求之后,服務端也要停止發送請求
4.time_wait存在的原因,時間是多少(兩倍的報文最大存活時間)
1.確保客戶端發送的最后一個報文能被收到,服務端可以正常關閉,
2.讓所有報文都在網路中消失,時間是兩倍的最大報文存活時間,
5.tcp的可靠傳輸靠什么:
超時重傳:如果已經發送的報文在超過時間內沒有被確認,那么就重新發送這個報文
6.Tcp的滑動視窗
發送方和接收方都有一個滑動視窗
7.TCP流量控制
流量控制是為了控制發送方的發送速率,保證接收方來得及接收
通過滑動視窗來控制,根據報文知道對方視窗的大小,然后根據視窗大小來控制發送速率
8.TCP擁塞控制
如報文過多,會導致超時重傳,又會導致網路更加阻塞

1.慢開始和擁塞避免:
慢開始:設定初始的報文數量為1;
擁塞避免:設定一個閾值,當報文數超過這個閾值的時候每次,報文每次加一,如果出現超時領閾值等于當前報文的一半,重新執行慢開始
快重傳:如果收到3個確認報文,則重傳丟失的那個報文
快恢復:這種情況令閾值等于當前報文的一半,并令當前發送的報文數等于閾值,因為沒有出現網路阻塞
http各個版本的區別
http0.9 : 僅支持GET請求,僅能訪問html資源
http 1.0 :增加了post和head請求
http1.1 : 增加了長連接,一個tcp連接可以發送多個http請求,新增了put,patch,delete請求
http2.0 : 增加了雙工模式,不僅客戶端能發送多個請求,服務端也能處理多個請求
Redis
1.redis的資料淘汰策略
當redis記憶體資料大小達到一定的大小時,就會施行資料淘汰策略,主要有六種策略

2.資料庫和快取的資料一致性
2.1 mySQL里有2000w資料,redis中只存20w的資料,如何保證redis中的資料都是熱點資料
根據資料淘汰策略,先算一下這20W的資料大概占多少記憶體,然后設定redis的記憶體,啟用從所有資料集中挑選最近最少使用的淘汰策略
2.2 redis快取和mysql資料庫同步
3.Redis持久化
1.RDB持久化(redis默認方式)
將某個時間點的所有資料都存在硬碟中,如果發生故障將丟失最后一次創建快照的資料
觸發RDB快照的條件:在指定的時間間隔內,執行指定次數的寫操作
2.AOF持久化
所執行的每一條指令,都會記錄到appendonly.aof檔案中,redis會按照策略將指令存入硬碟中,當redis重啟的時候會根據日志檔案的內容將寫指令從前到后執行一次完成資料恢復的功能
Java例外體系

Error:主要是虛擬機產生,與代碼撰寫者無關,例如:outOfMemoryError
Exception:主要有運行時例外和io例外
運行時例外:陣列越界,空指標例外
Io例外:找不到檔案
發生oom的可能區域:
除了程式計數器都有可能發生
虛擬機堆疊:當jvm嘗試去擴展堆疊空間失敗時可能會拋出oom例外
堆:堆中物件堆積起來無法釋放
方法區
四種參考型別:
主要體現在物件不可達性和對垃圾回收的影響:
強參考:只要有強參考指向一個物件,就表面物件還活著,垃圾回收期不會碰這種物件
軟參考:只有當jvm認為記憶體不足的時候才會去試圖回收這些物件
弱參考:不能使物件豁免垃圾回收,只是提供一種物件的訪問途徑
虛參考:不能提供他訪問物件,僅僅提供一種確保物件唄finalize之后做某些事情的機制
JAVA虛擬機是如果加載類的
1.加載:主要是用類加載器(啟動類加載器,擴展類加載器,應用類加載器)來查找對應類的位元組流
雙親委派的好處:由于類隨著類加載器一起有一種優先級的層級關系,從而使基礎類得到統一
2.鏈接
驗證:確保位元組流的安全性,不會對虛擬機造成危害
準備:為類的靜態欄位分配記憶體
決議:將符號參考決議成實際參考
3.初始化:呼叫<clinit>方法,為靜態變數賦與實際的值,執行靜態代碼塊
運行時資料區域:
運行時記憶體區域:
1.程式計數器:記錄正在執行虛擬機位元組碼的指令地址
2.java虛擬機堆疊:主要存盤區域變數表
3.本地方法堆疊
4.堆:存盤物件的地方,有新生代和老年代
5.方法區:存盤類資訊,常量,靜態變數等資訊
記憶體分配策略:
1.物件優先在eden區域分配
2.大物件直接進入老年代
3.長期存活的物件進入老年代:會有一個年齡計數器,達到指定的閾值就會進入老年代
FullGC觸發條件:
1.呼叫system.gc()
2.老年代空間不足
3.minor GC時老年代空間分配擔保失敗
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/279246.html
標籤:java
上一篇:2021-04-22
