一、JVM 基礎(chǔ)【重要】
一篇文章掌握整個(gè)JVM,JVM超詳細(xì)解析?。?!
什么是 JVM (Java虛擬機(jī))?
JVM (Java虛擬機(jī))
是運(yùn)行 Java 字節(jié)碼 的 虛擬機(jī)。- JVM 針對(duì) 不同系統(tǒng) 有 特定實(shí)現(xiàn) (Windows、Linux 等),目的是 同樣的代碼 在 不同平臺(tái) 能運(yùn)行出 相同的結(jié)果。
為什么說(shuō) Java 語(yǔ)言 “編譯與解釋并存”?
Java 語(yǔ)言 要經(jīng)過(guò) 編譯 和 解釋 兩個(gè)步驟:
編譯
:通過(guò) 編譯器 將 代碼一次性
編譯 成字節(jié)碼
。解釋
:通過(guò) 解釋器 將 代碼一句一句地
解釋 成機(jī)器代碼
。
Java類 加載過(guò)程?
點(diǎn)擊查看:JVM 類加載機(jī)制與加載過(guò)程
Java類 加載過(guò)程如下:
加載
:將硬盤上 Java字節(jié)碼文件 (Class文件) 轉(zhuǎn)為 內(nèi)存 中的 Class對(duì)象。驗(yàn)證
:檢查載入的 class文件數(shù)據(jù) 的 正確性。準(zhǔn)備 (重要)
:為 靜態(tài)變量 分配內(nèi)存,并設(shè)置為 初始值 (0、false、null 等)。解析
:將 常量池 內(nèi)的 符號(hào)引用 轉(zhuǎn)換為 直接引用。初始化
:為 類變量 (靜態(tài)變量) 賦值,執(zhí)行 靜態(tài)代碼塊。![]()
二、內(nèi)存管理【重要】
說(shuō)?下 JVM 的內(nèi)存區(qū)域 | 運(yùn)行時(shí)數(shù)據(jù)區(qū)是怎樣的?
Java內(nèi)存區(qū)域詳解 (重點(diǎn))
堆
: 線程共享。存放 對(duì)象實(shí)例、數(shù)組、字符串常量池 (也稱GC堆
)。虛擬機(jī)棧
:線程私有。存儲(chǔ)方法的內(nèi) 局部變量、操作數(shù) 等。本地方法棧
:線程私有。同虛擬機(jī)棧
,只不過(guò)是 本地方法。
【本地方法:就是 Java 調(diào)用的 非Java代碼 實(shí)現(xiàn)的接口】程序計(jì)數(shù)器
:線程私有。用于記錄 線程 當(dāng)前的 執(zhí)行的位置。元空間
:線程共享。元空間 就在 堆 中,存儲(chǔ) 類的元數(shù)據(jù)、靜態(tài)方法、靜態(tài)屬性。![]()
[了解] 什么是 Java內(nèi)存模型?
JMM
規(guī)定了 多線程環(huán)境 下所有的 變量 都存儲(chǔ)在 主內(nèi)存 中,從而保證變量的 可見性 和 有序性?!?strong>validate】
[了解] 棧幀 是什么?棧幀 有什么作用?
棧幀
是棧
的 組成單位。棧幀是一種數(shù)據(jù)結(jié)構(gòu),它封裝了以下信息:
局部變量表
:存儲(chǔ) 局部變量。動(dòng)態(tài)鏈接
:存儲(chǔ) 當(dāng)前方法 調(diào)用的 目標(biāo)方法 的 鏈接。方法返回地址
:存儲(chǔ) 目標(biāo)方法執(zhí)行完畢 后的 返回地址。
程序計(jì)數(shù)器 有什么作用?
點(diǎn)擊查看
程序計(jì)數(shù)器
主要有下面兩個(gè)作用:
程序計(jì)數(shù)器
用于記錄 線程 當(dāng)前的 執(zhí)行的位置。- 解釋器 通過(guò)改變
程序計(jì)數(shù)器
來(lái) 依次讀取指令。
什么是 內(nèi)存溢出?有哪些情況會(huì)導(dǎo)致 內(nèi)存溢出?
內(nèi)存溢出
(OOM) 是指 系統(tǒng) 沒(méi)有足夠的 內(nèi)存空間 可以 分配,從而出現(xiàn)的一種 異常。
導(dǎo)致內(nèi)存溢出的情況:
創(chuàng)建大量對(duì)象
內(nèi)存泄漏
什么是 內(nèi)存泄漏??jī)?nèi)存泄漏 有什么影響?
Java內(nèi)存泄露系列–內(nèi)存泄露的原因及解決方案(大全)
內(nèi)存泄露
:堆內(nèi)存 中的 對(duì)象 不再使用時(shí),垃圾回收器 卻 無(wú)法回收 該對(duì)象,導(dǎo)致 內(nèi)存泄露。
內(nèi)存泄漏 的影響:
- 長(zhǎng)時(shí)間連續(xù)運(yùn)行時(shí) 性能嚴(yán)重下降;
- 出現(xiàn) OOM 導(dǎo)致 應(yīng)用崩潰;
有哪些情況會(huì)導(dǎo)致 內(nèi)存泄漏?
Java中內(nèi)存泄露原因總結(jié)
靜態(tài)集合類
:靜態(tài)集合類(如ArrayList、HashMap) 生命周期與程序一致,程序結(jié)束之前 不會(huì)被釋放,會(huì)引起 內(nèi)存泄漏。連接(IO/數(shù)據(jù))未釋放
:如果連接不被顯性的關(guān)閉,會(huì)引起 內(nèi)存泄漏。
三、Java8 垃圾回收【重要】
1、垃圾回收流程
JVM–內(nèi)存模型/垃圾回收流程
Java 堆的內(nèi)存分區(qū)了解嗎?
Java堆內(nèi)存 的 內(nèi)存模型:
- 堆內(nèi)存 主要?jiǎng)澐譃?
年輕代
、老年代
、元空間
三個(gè)區(qū)域。- 年輕代 存放 存活時(shí)間短 的對(duì)象,每次 垃圾回收 后存活的對(duì)象,將會(huì)逐步存放到 老年代。
- 年輕代 又可以分為兩個(gè)區(qū)域:
Eden
、Survivor
,Survivor 分為From區(qū)
、To區(qū)
。![]()
JDK8 垃圾回收 的 流程?
JVM–內(nèi)存模型/垃圾回收流程
- 1、創(chuàng)建一個(gè)新對(duì)象 時(shí),JVM會(huì)將 新對(duì)象 保存在
年輕代
的Eden區(qū)
,如果 Eden區(qū) 的 空間 不足,則會(huì)執(zhí)行Minor GC
(年輕代GC)。- 2、Minor GC 會(huì)將 Eden區(qū) 和
From區(qū)
中的 存活對(duì)象 復(fù)制到To區(qū)
,然后清空 Eden區(qū) 和 From區(qū)。- 3、如果 To區(qū) 的 空間 不足,會(huì)繼續(xù)進(jìn)行 Minor GC,部分 年輕代對(duì)象 會(huì)逐漸放入
老年代
,直到 To區(qū) 的 空間 充足。- 4、如果此時(shí) 老年代 的 內(nèi)存 不足,則將執(zhí)行
Full GC
。- 5、
Full GC
后,如果 老年代 的 內(nèi)存 仍然不足,則會(huì)拋出 內(nèi)存溢出 (OOM) 錯(cuò)誤,程序中斷運(yùn)行。
什么是 Stop The World?
垃圾回收 時(shí),會(huì)涉及 對(duì)象的移動(dòng)。為了保證 對(duì)象引用 的正確性,必須 暫停所有線程,這樣的停頓被稱為
Stop The World
(STW)。
(了解) 對(duì)象有哪幾種引用?
Java引用類型(強(qiáng)引用、軟引用、弱引用、虛引用)的區(qū)別
強(qiáng)引用
:代碼中普遍存在的 賦值引用。強(qiáng)引用 關(guān)聯(lián)的對(duì)象,不會(huì)被 垃圾收集器 回收。軟引用
:軟引用 關(guān)聯(lián)的對(duì)象,MinorGC 第二次遇到 軟引用對(duì)象 才會(huì)進(jìn)行回收。(第一次只進(jìn)行 標(biāo)記)弱引用
:弱引用 關(guān)聯(lián)的對(duì)象,會(huì)被 垃圾收集器 回收。虛引用
:最弱的?種 引用關(guān)系,不會(huì)影響對(duì)象的 生存時(shí)間。
2、垃圾收集器
垃圾收集算法 有哪些?
復(fù)制算法
【年輕代 垃圾回收 一般都是基于 復(fù)制算法】標(biāo)記-清除算法
標(biāo)記-整理算法
垃圾收集器都有哪些?
- Minor GC 垃圾收集器:
Parallel
(并行)、Serial
(串行)- Full GC 垃圾收集器:
CMS
、G1
CMS 和 G1 區(qū)別?
CMS收集器和G1收集器的區(qū)別
CMS
基于標(biāo)記-清除算法
。G1
基于標(biāo)記-整理算法
(整體) 和復(fù)制算法
(局部)。CMS
并發(fā)清除階段 會(huì)導(dǎo)致 內(nèi)存碎片比過(guò)多。G1
主要解決了內(nèi)存碎片過(guò)多
的問(wèn)題。- Java8 默認(rèn)使用 CMS 回收 老年代。
![]()
說(shuō)一下 CMS 垃圾收集器 的工作過(guò)程?
CMS 垃圾收集器 使用
標(biāo)記-清除算法
,收集過(guò)程分為四步:
初始標(biāo)記
:標(biāo)記 GC Roots 能 直達(dá)的對(duì)象。需要STW
。并發(fā)標(biāo)記
:從 GC Roots 能 直達(dá)的對(duì)象 開始 遍歷,找出要 回收的對(duì)象。重新標(biāo)記
:標(biāo)記 并發(fā)標(biāo)記階段 產(chǎn)生的對(duì)象。需要STW
。并發(fā)清除
:清理掉 標(biāo)記階段 標(biāo)記的對(duì)象。
說(shuō)一下 G1 垃圾收集器 的工作過(guò)程?
G1 收集器 使用了
復(fù)制算法
和標(biāo)記-整理算法
,收集過(guò)程分為四步:文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-617152.html
初始標(biāo)記
:標(biāo)記 GC Roots 能 直達(dá)的對(duì)象。需要STW
。并發(fā)標(biāo)記
:從 GC Roots 能 直達(dá)的對(duì)象 開始 遍歷,找出要 回收的對(duì)象。重新標(biāo)記
:標(biāo)記 并發(fā)標(biāo)記階段 產(chǎn)生的對(duì)象。需要STW
。篩選回收
:選擇多個(gè) Region 構(gòu)成 回收集,把 回收集 中 的 存活對(duì)象 復(fù)制到 空的 Region 中,再清理掉 舊 Region 的全部空間。需要STW
。
哪些 對(duì)象 可以作為 GC Root?
靜態(tài)屬性
引用的對(duì)象實(shí)例屬性
引用的對(duì)象棧
中引用的對(duì)象
判斷 垃圾對(duì)象 的方法有哪些?
引用計(jì)數(shù)法
:缺點(diǎn):當(dāng)兩個(gè)垃圾對(duì)象 互相引用 時(shí),不會(huì) 被判定為 垃圾對(duì)象。可達(dá)性分析
四、JVM 調(diào)優(yōu)
JVM通常設(shè)置哪些參數(shù)來(lái)調(diào)優(yōu)?
-Xms
:初始堆大小。-Xmx
:最大堆大小:一般將 Xms 和 Xmx 設(shè)為一樣的值,避免重新分配內(nèi)存。-Xmn
:設(shè)置 年輕代空間大小。
堆內(nèi)存、新生代、老年代 一般設(shè)置為多大內(nèi)存?
Java — 堆內(nèi)存、新生代、老年代 一般設(shè)置為多大內(nèi)存?文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-617152.html
堆內(nèi)存
:通常將 最大堆內(nèi)存大小 設(shè)置為可用 物理內(nèi)存的1/2
到2/3
。新生代
:通常設(shè)置為整個(gè) 堆內(nèi)存 的1/3
。老年代
:通常設(shè)置為整個(gè) 堆內(nèi)存 的2/3
。
頻繁 Minor GC 怎么辦?
頻繁 Minor GC 的原因
:新生代 空間較小,Eden 區(qū) 和 To區(qū) 很快會(huì)被填滿。解決方法
:可以通過(guò) 增大新生代空間-Xmn
來(lái)降低 Minor GC 的頻率。
到了這里,關(guān)于3.Java面試題—JVM基礎(chǔ)、內(nèi)存管理、垃圾回收、JVM 調(diào)優(yōu)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!