面試 JVM 八股文五問五答第一期

面試 JVM 八股文五問五答第一期

作者:程序員小白條,個人博客

相信看了本文后,對你的面試是有一定幫助的!

?點贊?收藏?不迷路!?

1.JVM內存布局

Heap (堆區)

堆是 OOM 故障最主要的發生區域。它是內存區域中最大的一塊區域,被所有線程共享,存儲著幾乎所有的實例對象、數組。

Java 堆是垃圾收集器管理的主要區域,因此很多時候也被稱做“GC 堆”。從內存回收的角度來看,由于現在收集器基本都采用分代收集算法,所以 Java 堆中還可以細分為:新生代和老年代。再細致一點的有 Eden 空間、From Survivor 空間、To Survivor 空間等。從內存分配的角度來看,線程共享的 Java 堆中可能劃分出多個線程私有的分配緩沖區(Thread Local Allocation Buffer,TLAB)。不過無論如何劃分,都與存放內容無關,無論哪個區域,存儲的都仍然是對象實例,進一步劃分的目的是為了更好地回收內存,或者更快地分配內存。

堆區的調整:通過設置如下參數,可以設定堆區的初始值和最大值,比如 -Xms256M -Xmx 1024M,其中 -X 這個字母代表它是 JVM 運行時參數,ms 是 memory start 的簡稱,中文意思就是內存初始值,mx 是 memory max 的簡稱,意思就是最大內存。

在通常情況下,服務器在運行過程中,堆空間不斷地擴容與回縮,會形成不必要的系統壓力所以在線上生產環境中 JVM 的 Xms 和 Xmx 會設置成同樣大小,避免在 GC 后調整堆大小時帶來的額外壓力。

堆的默認空間分配:查看當前 JDK 版本所有默認的 JVM 參數:=======》java -XX:+PrintFlagsFinal -version

Java 虛擬機棧:

對于每一個線程,JVM 都會在線程被創建的時候,創建一個單獨的棧。也就是說虛擬機棧的生命周期和線程是一致,并且是線程私有的。

棧幀(Stack Frame)是用于支持虛擬機進行方法調用和方法執行的數據結構。棧幀存儲了方法的局部變量表(局部變量表:定義為一個數字數組,用于方法參數和方法內部的局部變量,包括三種數據類型:8種基本數據類型+引用數據類型地址+returnAddress類型(指向一條字節碼指令的地址) )、操作數棧(操作數棧主要用于保存運算過程中的的中間結果,同時作為計算過程中變量的臨時的存儲空間.)、動態鏈接(動態鏈接就是講指令中的符號引用轉化為真實的方法地址(直接引用)和方法返回地址等信息。每一個方法從調用至執行完成的過程,都對應著一個棧幀在虛擬機棧里從入棧到出棧的過程。

本地方法棧:

本地方法棧(Native Method Stack)與虛擬機棧所發揮的作用是非常相似的,它們之間的區別不過是虛擬機棧為虛擬機執行 Java 方法(也就是字節碼)服務,而本地方法棧則為虛擬機使用到的 Native 方法服務。在虛擬機規范中對本地方法棧中方法使用的語言、使用方式與數據結構并沒有強制規定,因此具體的虛擬機可以自由實現它。甚至有的虛擬機(譬如 Sun HotSpot 虛擬機)直接就把本地方法棧和虛擬機棧合二為一。與虛擬機棧一樣,本地方法棧區域也會拋出 StackOverflowError 和 OutOfMemoryError 異常。

拓展:

  • 靜態鏈接:當一個字節碼文件被裝載進JVM內部時,如果被調用的目標方法在編譯器可知,且運行時期不變,這種情況下將調用方法的符號引用轉換為直接引用的過程稱之為靜態鏈接.對應早期綁定(早期綁定就是指被調用的目標方法如果在編譯期可知,且運行時期不變,即可將這個方法與所屬的類型進行綁定,這樣以來,由于明確了被調用的方法是哪一個,因此可以使用靜態鏈接的方式將符號引用轉換為直接引用).
  • 動態鏈接:如果被調用的方法在編譯期無法被確定下來,只能夠在程序運行期將調用方法的符號引用轉換為直接引用,由于這種引用轉換過程具備動態性,因此被稱之為動態鏈接.對應晚期綁定(如果被調用方法在編譯期無法被確定下來,只能在程序運行期根據實際的類型綁定相應的方法,這種綁定方式被稱為晚期綁定).

程序計數器:

程序計數器(Program Counter Register)是一塊較小的內存空間。是線程私有的。它可以看作是當前線程所執行的字節碼的行號指示器

直接內存:

直接內存(Direct Memory)并不是虛擬機運行時數據區的一部分,也不是 Java 虛擬機規范中定義的內存區域。但是這部分內存也被頻繁地使用,而且也可能導致 OutOfMemoryError 異常出現

Code Cache:

JVM 代碼緩存是 JVM 將其字節碼存儲為本機代碼的區域 。我們將可執行本機代碼的每個塊稱為 nmethod。該 nmethod 可能是一個完整的或內聯 Java 方法。

2.Java如何標記垃圾

Java中的垃圾回收是通過標記-清除算法實現的。當一個對象不再被任何引用指向時,它就可以被垃圾回收器回收。

在Java中,垃圾回收器通過可達性分析算法來標記垃圾對象。可達性分析算法是從一組被稱為“GC Roots”的根對象開始遍歷內存中的所有對象,任何能夠被遍歷到的對象都被認為是“存活”的對象,而未被遍歷到的對象則被認為是“垃圾”對象。

Java中的GC Roots包括以下幾種類型的對象:

  1. 虛擬機棧中引用的對象
  2. 方法區中靜態屬性引用的對象
  3. 方法區中常量引用的對象
  4. 本地方法棧中JNI(Java Native Interface)引用的對象

垃圾回收器會從GC Roots開始遍歷內存中的所有對象,標記出所有被引用的對象,然后將沒有被標記的對象視為垃圾對象進行回收。這個過程中,需要注意的是,垃圾回收器不能回收互相引用的對象,即使這些對象已經沒有任何被引用的路徑,因為它們之間仍然存在一條循環引用的路徑,所以它們仍然被視為“存活”的對象。

需要注意的是,Java虛擬機的垃圾回收機制是自動的,程序員無法直接干預。但是,可以通過一些手段來優化垃圾回收的效率,比如盡量避免創建大量的臨時對象,避免使用過多的finalize()方法等。

3.GC回收的是哪里?

因為虛擬機棧、本地方法棧、程序計數器是線程私有的,隨著線程的消亡而消亡,方法結束或者線程結束時,內存自然就跟隨著回收了。 GC回收的區域是堆和方法區,為什么回收這兩個區域那,因為他們是線程共享的,即java程序中所有的線程都可以訪問。

4.常見的垃圾回收算法有哪些?

**分代收集算法:**根據內存對象的存活周期不同,將內存劃分成幾塊,java虛擬機一般將內存分成新生代和老生代,在新生代中,有大量對象死去和少量對象存活,所以采用復制算法,只需要付出少量存活對象的復制成本就可以完成收集;老年代中因為對象的存活率極高,沒有額外的空間對他進行分配擔保,所以采用標記清理或者標記整理算法進行回收;

**標記清除法:**第一步:利用可達性去遍歷內存,把存活對象和垃圾對象進行標記;

第二步:在遍歷一遍,將所有標記的對象回收掉;

特點:效率不行,標記和清除的效率都不高;標記和清除后會產生大量的不連續的空間分片,可能會導致之后程序運行的時候需分配大對象而找不到連續分片而不得不觸發一次GC(垃圾回收);

**標記整理法:**第一步:利用可達性去遍歷內存,把存活對象和垃圾對象進行標記;第二步:將所有的存活的對象向一段移動,將端邊界以外的對象都回收掉;

特點:適用于存活對象多,垃圾少的情況;需要整理的過程,無空間碎片產生;

**復制算法:**將內存按照容量大小分為大小相等的兩塊,每次只使用一塊,當一塊使用完了,就將還存活的對象移到另一塊上,然后在把使用過的內存空間移除;特點:不會產生空間碎片;內存使用率極低;

5.哪些情況下會出現FULLGC

  1. 調用 System.gc()

只是建議虛擬機執行 Full GC,但是虛擬機不一定真正去執行。不建議使用這種方式,而是讓虛擬機管理內存。

  1. 未指定老年代和新生代大小,堆伸縮時會產生fullgc,所以一定要配置-Xmx、-Xms
  2. 老年代空間不足

老年代空間不足的常見場景比如大對象、大數組直接進入老年代、長期存活的對象進入老年代等。

為了避免以上原因引起的 Full GC,應當盡量不要創建過大的對象以及數組。

除此之外,可以通過 -Xmn 虛擬機參數調大新生代的大小,讓對象盡量在新生代被回收掉,不進入老年代。

還可以通過 -XX:MaxTenuringThreshold 調大對象進入老年代的年齡,讓對象在新生代多存活一段時間。

在執行Full GC后空間仍然不足,則拋出錯誤:java.lang.OutOfMemoryError: Java heap space

  1. JDK 1.7 及以前的(永久代)空間滿

在 JDK 1.7 及以前,HotSpot 虛擬機中的方法區是用永久代實現的,永久代中存放的為一些 Class 的信息、常量、靜態變量等數據。

當系統中要加載的類、反射的類和調用的方法較多時,永久代可能會被占滿,在未配置為采用 CMS GC 的情況下也

會執行 Full GC。

如果經過 Full GC 仍然回收不了,那么虛擬機會拋出java.lang.OutOfMemoryError PermGen space

為避免以上原因引起的 Full GC,可采用的方法為增大Perm Gen或轉為使用 CMS GC。

  1. 空間分配擔保失敗

空間擔保,下面兩種情況是空間擔保失敗:

1、每次晉升的對象的平均大小 > 老年代剩余空間

2、Minor GC后存活的對象超過了老年代剩余空間

注意GC日志中是否有promotion failed和concurrent mode failure兩種狀況,當出現這兩種狀況的時候就有可能會觸發Full GC。

promotion failed 是在進行 Minor GC時候,survivor space空間放不下只能晉升老年代,而此時老年代也空間不足時發生的。

concurrent mode failure 是在進行CMS GC過程,此時有對象要放入老年代而空間不足造成的,這種情況下會退化使用Serial Old收集器變成單線程的,此時是相當的慢的。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/215402.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/215402.shtml
英文地址,請注明出處:http://en.pswp.cn/news/215402.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

大數據畢業設計之前端03:logo、menu的折疊展開實現

關鍵字:BuildAdmin、pinia、logo、aside、menu、菜單折疊、Vue、ElementUI 前言 上一篇文章中,借助aside的實現講了一些開發的小技巧,以及css的解讀。本篇文章主要寫一下如何填充aside的內容。 aside主要是由兩個部分組成的:log…

數據結構與算法-Rust 版讀書筆記-2線性數據結構-棧

數據結構與算法-Rust 版讀書筆記-2線性數據結構-棧 一、線性數據結構概念 數組、棧、隊列、雙端隊列、鏈表這類數據結構都是保存數據的容器,數據項之間的順序由添加或刪除時的順序決定,數據項一旦被添加,其相對于前后元素就會一直保持位置不…

電腦入門基礎知識

1.電腦鍵盤個數一般都是有多少個? 答:一般情況下,電腦鍵盤只有一個。但是,也有一些特殊的情況,例如游戲玩家可能會使用額外的游戲鍵盤,或者一些專業人士可能會使用多個鍵盤來提高工作效率。但是在大多數情…

[Spring~源碼] ControllerAdvice揭秘

在Spring MVC中,我們經常使用ControllerAdvice注解,可以實現全局統一異常處理、全局數據綁定等功能。但是,它的實現原理是什么呢?在本文中,我們將深入探究ControllerAdvice的實現原理。 文章目錄 什么是ControllerAdvi…

docker-compose.yml文件配置詳解

簡介 Compose 是用于定義和運行多容器 Docker 應用程序的工具。通過 Compose,您可以使用 YML 文件來配置應用程序需要的所有服務。然后,使用一個命令,就可以從 YML 文件配置中創建并啟動所有服務。 docker compose文件是一個yaml格式的文件&a…

【Hadoop_04】HDFS的API操作與讀寫流程

1、HDFS的API操作1.1 客戶端環境準備1.2 API創建文件夾1.3 API上傳1.4 API參數的優先級1.5 API文件夾下載1.6 API文件刪除1.7 API文件更名和移動1.8 API文件詳情和查看1.9 API文件和文件夾判斷 2、HDFS的讀寫流程(面試重點)2.1 HDFS寫數據流程2.2 網絡拓…

學會面向對象經典練習題21道

1.面向對象練習:設計小狗類 需求: 抽象形成一個小狗類Dog 屬性:名字name 年齡age 品種kind 主人host 價格price 功能: 跑run:無參,打印:小狗Dog跑的老快了~ 吃eat:參數int n&#x…

當MongoDB主鍵為String時,mongoTemplate無法根據id查詢的問題

MongoDB推薦使用ObjectId作為主鍵,但國內的開發都知道,事情往往不如人所愿,當我們真的出現了“_id”主鍵的類型為String時,且還必須想用mongoTemplate.findOne或findList時,直接使用該方法會導致查詢結果為空。 因為m…

https 協議

目錄 加密方式 對稱加密 非對稱加密 非對稱加密 非對稱加密 非對稱加密 對稱加密 AC證書 AC證書內容 數據摘要 數據簽名 在我們前面學習的http協議里面,我們發送的內容都是明文傳輸的,所以在安全上并不安全,但是在現在信息發達的時…

Java高級技術:優化性能與擴展性的最佳實踐

標題:Java高級技術:優化性能與擴展性的最佳實踐 摘要:本文將介紹Java中一些高級技術,以提高性能和代碼的擴展性。本文不包括反射和并發編程,旨在幫助開發者進一步提升Java應用程序的質量和可維護性。 優化性能的最佳實…

面試題目總結(三)

1. Spring、Springboot、springMVC、Spring Cloud 的區別: Spring:Spring 是一個開源的、輕量級的Java框架,提供了豐富的功能和組件,用于構建企業級應用程序。Spring框架包含了很多模塊,包括核心容器、數據訪問、事物…

MATLAB算法實戰應用案例精講-【數模應用】漫談機器學習(七)

目錄 幾個高頻面試題目 機器學習算法工程師需要掌握哪些編程語言? 1.Python 2. C# 3.JavaScript 4. R 5.Java

Linux之Apache服務器安裝及配置

一、Apache服務器簡介 Apache HTTP Server(簡稱Apache)是Apache軟件基金會的一個開放源碼的網頁服務器,可以在大多數計算機操作系統中運行,由于其多平臺和安全性被廣泛使用。Apache曾經是世界使用排名第一的Web服務器軟件&#xf…

VSCODE連接遠程服務器

安裝ssh插件 根據你的操作系統選擇對應的版本進行下載和安裝。 安裝完成之后,啟動vscode,選擇左側Extensions 選項卡,在輸入框搜索 remote ,選擇安裝Remote-SSH插件。 安裝完成之后會在左側新增一個選項卡Remote Explorer&#xf…

肥貓游戲報價器|計價器|王者榮耀代練陪練等游戲報價器軟件介紹說明

目錄 1. 前言2. 軟件著作權3. 軟件使用說明3.1 進入軟件3.2 用戶登錄3.3 首頁3.4 報價器3.4.1 總體介紹3.4.2 王者報價器3.4.3 LOL手游報價器3.4.4 英雄聯盟報價器3.4.5 云頂之弈報價器3.4.7 王者水晶報價器3.4.8 和平精英報價器3.4.9 蛋仔派對報價器3.4.10 穿越火線報價器3.4.…

kafka學習筆記--broker工作流程、重要參數

本文內容來自尚硅谷B站公開教學視頻,僅做個人總結、學習、復習使用,任何對此文章的引用,應當說明源出處為尚硅谷,不得用于商業用途。 如有侵權、聯系速刪 視頻教程鏈接:【尚硅谷】Kafka3.x教程(從入門到調優…

Linux mc命令教程:如何有效地使用mc命令(附案例詳解和注意事項)

Linux mc命令介紹 mc命令是Linux中的一個視覺文件管理器,全稱為Midnight Commander。它提供了一個用戶友好的界面,使得在Linux環境中的文件和目錄管理變得更加直觀和方便。mc命令支持鼠標操作和顏色顯示,同時也提供了一套菜單接口&#xff0…

TypeScript 常用高級類型

目錄 前言: TypeScript 常用高級類型 基本概念 高級類型 1. 交叉類型(Intersection Types) 2. 聯合類型(Union Types) 3. 映射類型(Mapped Types) 4. 條件類型(Conditional…

GGML 或GGUF的14種不同量化模式說明

查看 TheBloke/Llama-2–13B-chat-GGML 存儲庫中的文件,我們可以看到 14 種不同的 GGML 模型,對應于不同類型的量化。它們遵循特定的命名約定:“q” 用于存儲權重的位數(精度) 特定變體。以下是所有可能的量化方法及其…

Pytorch-Transformer軸承故障一維信號分類(三)

目錄 前言 1 數據集制作與加載 1.1 導入數據 第一步,導入十分類數據 第二步,讀取MAT文件驅動端數據 第三步,制作數據集 第四步,制作訓練集和標簽 1.2 數據加載,訓練數據、測試數據分組,數據分batch…