常見 JVM 面試題補充

原文地址 :?26 福利:常見 JVM 面試題補充 (lianglianglee.com)

CMS 是老年代垃圾回收器?

初步印象是,但實際上不是。根據 CMS 的各個收集過程,它其實是一個涉及年輕代和老年代的綜合性垃圾回收器。在很多文章和書籍的劃分中,都將 CMS 劃分為了老年代垃圾回收器,加上它主要作用于老年代,所以一般誤認為是。

常量池問題

常量池的表述有些模糊,在此細化一下,注意我們指的是 Java 7 版本之后。

JVM 中有多個常量池:

  • 字符串常量池,存放在堆上,也就是執行 intern 方法后存的地方,class 文件的靜態常量池,如果是字符串,則也會被裝到字符串常量池中。
  • 運行時常量池,存放在方法區,屬于元空間,是類加載后的一些存儲區域,大多數是類中 constant_pool 的內容。
  • 類文件常量池,也就是 constant_pool,這個是概念性的,并沒有什么實際存儲區域。

在平常的交流過程中,聊的最多的是字符串常量池,具體可參考官網。

永久代

常見面試題

JVM 有哪些內存區域?(JVM 的內存布局是什么?)

JVM 包含堆、元空間、Java 虛擬機棧、本地方法棧、程序計數器等內存區域,其中,堆是占用內存最大的一塊,如下圖所示。

Java 的內存模型是什么?(JMM 是什么?)

JVM 試圖定義一種統一的內存模型,能將各種底層硬件以及操作系統的內存訪問差異進行封裝,使 Java 程序在不同硬件以及操作系統上都能達到相同的并發效果。它分為工作內存和主內存,線程無法對主存儲器直接進行操作,如果一個線程要和另外一個線程通信,那么只能通過主存進行交換,如下圖所示。

JVM 垃圾回收時如何確定垃圾?什么是 GC Roots?

JVM 采用的是可達性分析算法。JVM 是通過 GC Roots 來判定對象存活的,從 GC Roots 向下追溯、搜索,會產生一個叫做 Reference Chain 的鏈條。當一個對象不能和任何一個 GC Root 產生關系時,就判定為垃圾,如下圖所示。

GC Roots 包括:

  • Java 線程中,當前所有正在被調用的方法的引用類型參數、局部變量、臨時值等。也就是與我們棧幀相關的各種引用。
  • 所有當前被加載的 Java 類。
  • Java 類的引用類型靜態變量。
  • 運行時常量池里的引用類型常量(String 或 Class 類型)。
  • JVM 內部數據結構的一些引用,比如 sun.jvm.hotspot.memory.Universe 類。
  • 用于同步的監控對象,比如調用了對象的 wait() 方法。
  • JNI handles,包括 global handles 和 local handles。

這些 GC Roots 大體可以分為三大類,下面這種說法更加好記一些:

  • 活動線程相關的各種引用。
  • 類的靜態變量的引用。
  • JNI 引用。

能夠找到 Reference Chain 的對象,就一定會存活么?

不一定,還要看 Reference 類型,弱引用在 GC 時會被回收,軟引用在內存不足的時候會被回收,但如果沒有 Reference Chain 對象時,就一定會被回收。

強引用、軟引用、弱引用、虛引用是什么?

普通的對象引用關系就是強引用。

軟引用用于維護一些可有可無的對象。只有在內存不足時,系統則會回收軟引用對象,如果回收了軟引用對象之后仍然沒有足夠的內存,才會拋出內存溢出異常。

弱引用對象相比軟引用來說,要更加無用一些,它擁有更短的生命周期,當 JVM 進行垃圾回收時,無論內存是否充足,都會回收被弱引用關聯的對象。

虛引用是一種形同虛設的引用,在現實場景中用的不是很多,它主要用來跟蹤對象被垃圾回收的活動。

你說你做過 JVM 參數調優和參數配置,請問如何查看 JVM 系統默認值

使用 -XX:+PrintFlagsFinal 參數可以看到參數的默認值,這個默認值還和垃圾回收器有關,比如 UseAdaptiveSizePolicy。

你平時工作中用過的 JVM 常用基本配置參數有哪些?

主要有 Xmx、Xms、Xmn、MetaspaceSize 等。

請你談談對 OOM 的認識

OOM 是非常嚴重的問題,除了程序計數器,其他內存區域都有溢出的風險。和我們平常工作最密切的,就是堆溢出,另外,元空間在加載的類非常多的情況下也會溢出,還有就是棧溢出,這個通常影響比較小。堆外也有溢出的可能,這個就比較難排查了。

你都有哪些手段用來排查內存溢出?

這個話題很大,可以從實踐環節中隨便摘一個進行總結,下面舉一個最普通的例子。

內存溢出包含很多種情況,我在平常工作中遇到最多的就是堆溢出。有一次線上遇到故障,重新啟動后,使用 jstat 命令,發現 Old 區一直在增長。我使用 jmap 命令,導出了一份線上堆棧,然后使用 MAT 進行分析,通過對 GC Roots 的分析,發現了一個非常大的 HashMap 對象,這個原本是其他同事做緩存用的,但是一個無界緩存,造成了堆內存占用一直上升,后來,將這個緩存改成 guava 的 Cache,并設置了弱引用,故障就消失了。

GC 垃圾回收算法與垃圾收集器的關系?

常用的垃圾回收算法有標記清除、標記整理、復制算法等,引用計數器也算是一種,但垃圾回收器不使用這種算法,因為有循環依賴的問題。

很多垃圾回收器都是分代回收的:

  • 對于年輕代,主要有 Serial、ParNew 等垃圾回收器,回收過程主要使用復制算法;
  • 老年代的回收算法有 Serial、CMS 等,主要使用標記清除、標記整理算法等。

我們線上使用較多的是 G1,也有年輕代和老年代的概念,不過它是一個整堆回收器,它的回收對象是小堆區 。

怎么查看服務器默認的垃圾回收器是哪一個?

這通常會使用另外一個參數,即 -XX:+PrintCommandLineFlags,來打印所有的參數,包括使用的垃圾回收器。

假如生產環境 CPU 占用過高,請談談你的分析思路和定位。

首先,使用 top -H 命令獲取占用 CPU 最高的線程,并將它轉化為十六進制。

然后,使用 jstack 命令獲取應用的棧信息,搜索這個十六進制,這樣就能夠方便地找到引起 CPU 占用過高的具體原因。

對于 JDK 自帶的監控和性能分析工具用過哪些?

  • jps:用來顯示 Java 進程;
  • jstat:用來查看 GC;
  • jmap:用來 dump 堆;
  • jstack:用來 dump 棧;
  • jhsdb:用來查看執行中的內存信息。

棧幀都有哪些數據?

棧幀包含:局部變量表、操作數棧、動態連接、返回地址等。

JIT 是什么?

為了提高熱點代碼的執行效率,在運行時,虛擬機將會把這些代碼編譯成與本地平臺相關的機器碼,并進行各種層次的優化,完成這個任務的編譯器,就稱為即時編譯器(Just In Time Compiler),簡稱 JIT 編譯器。

Java 的雙親委托機制是什么?

雙親委托的意思是,除了頂層的啟動類加載器以外,其余的類加載器,在加載之前,都會委派給它的父加載器進行加載,這樣一層層向上傳遞,直到祖先們都無法勝任,它才會真正的加載,Java 默認是這種行為。

有哪些打破了雙親委托機制的案例?

  • Tomcat 可以加載自己目錄下的 class 文件,并不會傳遞給父類的加載器;
  • Java 的 SPI,發起者是 BootstrapClassLoader,BootstrapClassLoader 已經是最上層了,它直接獲取了

簡單描述一下(分代)垃圾回收的過程

分代回收器有兩個分區:老生代和新生代,新生代默認的空間占總空間的 1/3,老生代的默認占比是 2/3。

新生代使用的是復制算法,新生代里有 3 個分區:Eden、To Survivor、From Survivor,它們的默認占比是 8:1:1。

當年輕代中的 Eden 區分配滿的時候,就會觸發年輕代的 GC(Minor GC),具體過程如下:

  • 在 Eden 區執行了第一次 GC 之后,存活的對象會被移動到其中一個 Survivor 分區(以下簡稱 from);
  • Eden 區再次 GC,這時會采用復制算法,將 Eden 和 from 區一起清理,存活的對象會被復制到 to 區,接下來,只要清空 from 區就可以了。

CMS 分為哪幾個階段?

  • 初始標記
  • 并發標記
  • 并發預清理
  • 并發可取消的預清理
  • 重新標記
  • 并發清理

由于《深入理解 Java 虛擬機》一書的流行,面試時省略并發清理并發可取消的預清理這兩個階段一般也是沒問題的。

CMS 都有哪些問題?

  • 內存碎片問題,Full GC 的整理階段,會造成較長時間的停頓;
  • 需要預留空間,用來分配收集階段產生的“浮動垃圾”;
  • 使用更多的 CPU 資源,在應用運行的同時進行堆掃描;
  • 停頓時間是不可預期的。

什么情況會造成元空間溢出?

元空間默認是沒有上限的,不加限制比較危險。當應用中的 Java 類過多時,比如 Spring 等一些使用動態代理的框架生成了很多類,如果占用空間超出了我們的設定值,就會發生元空間溢出。

什么時候會造成堆外內存溢出?

使用了 Unsafe 類申請內存,或者使用了 JNI 對內存進行操作,這部分內存是不受 JVM 控制的,不加限制使用的話,會很容易發生內存溢出。

SWAP 會影響性能么?

當操作系統內存不足時,會將部分數據寫入到 SWAP ,但是 SWAP 的性能是比較低的。如果應用的訪問量較大,需要頻繁申請和銷毀內存,那么很容易發生卡頓。一般在高并發場景下,會禁用 SWAP。

有什么堆外內存的排查思路?

進程占用的內存,可以使用 top 命令,看 RES 段占用的值,如果這個值大大超出我們設定的最大堆內存,則證明堆外內存占用了很大的區域。 使用 gdb 命令可以將物理內存 dump 下來,通常能看到里面的內容。更加復雜的分析可以使用 Perf 工具,或者谷歌開源的 GPerftools。那些申請內存最多的 native 函數,就很容易找到。

HashMap 中的 key,可以是普通對象么?有什么需要注意的地方?

Map 的 key 和 value 可以是任何類型,但要注意的是,一定要重寫它的 equals 和 hashCode 方法,否則容易發生內存泄漏。

怎么看死鎖的線程?

通過 jstack 命令,可以獲得線程的棧信息,死鎖信息會在非常明顯的位置(一般是最后)進行提示。

MinorGC、MajorGC、FullGC 都什么時候發生?

MinorGC 在年輕代空間不足的時候發生,MajorGC 指的是老年代的 GC,出現 MajorGC 一般經常伴有 MinorGC。

FullGC 有三種情況:第一,當老年代無法再分配內存的時候;第二,元空間不足的時候;第三,顯示調用 System.gc 的時候。另外,像 CMS 一類的垃圾回收器,在 MinorGC 出現 promotion failure 的時候也會發生 FullGC。

類加載有幾個過程?

加載、驗證、準備、解析、初始化。

什么情況下會發生棧溢出?

棧的大小可以通過 -Xss 參數進行設置,當遞歸層次太深的時候,則會發生棧溢出。


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

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

相關文章

SpringCloud Alibaba的相關組件的簡介及其使用

Spring Cloud Alibaba是阿里巴巴為開發者提供的一套微服務解決方案,它基于Spring Cloud項目,提供了一系列功能強大的組件,包括服務注冊與發現、配置中心、熔斷與限流、消息隊列等。 本文將對Spring Cloud Alibaba的相關組件進行簡介&#xff…

React Native 之 動畫Animated(十二)

react-native 的 Animated API提供了一種聲明式的方式來創建平滑的動畫效果。它允許你編寫動畫邏輯,并將動畫值直接綁定到組件的樣式或布局屬性上。 react-native 的 Animated 庫通過以下方式工作: 創建動畫值:首先,你需要使用 A…

ROCm上運行預訓練BERT

14.10. 預訓練BERT — 動手學深度學習 2.0.0 documentation (d2l.ai) 下載數據集 在d2l-zh/pytorch/data目錄解壓: ~/d2l-zh/pytorch/data$ unzip wikitext-2-v1.zip Archive: wikitext-2-v1.zipcreating: wikitext-2/inflating: wikitext-2/wiki.test.tokens …

【第17章】MyBatis-Spring之注入映射器

文章目錄 前言一、注冊映射器1. XML 配置2. Java 配置 二、發現映射器1. <mybatis:scan/>2.MapperScan ( 建議 ) \color{#00FF00}{(建議)} (建議) 三、MapperScannerConfigurer總結 前言 與其在數據訪問對象&#xff08;DAO&#xff09;中手工編寫使用 SqlSessionDaoSu…

數據庫--數據庫基礎(一)

目錄 第一章 緒論 一.數據庫的基本概念 1. 數據庫的4個基本概念 2、數據庫系統的特點 二.數據庫和文件 三.數據模型 1.概念模型 2.邏輯模型(物理模型) 2.1關系模型 四.數據庫系統的三級模式結構&#xff1a; 五數據庫的二級映像功能與數據獨立性 第二章 關系數據庫…

WEBPACK開發|生產環境配置(抽離公共部分)

這是webpack4演示&#xff0c;webpack5有些插件不在推薦&#xff0c; 1. webpack.base.config.js文件的配置說明 const path require(path); const webpack require(webpack); const ExtractTextPlugin require(extract-text-webpack-plugin); // 該插件的主要是為了抽離c…

【LeetCode面試經典150題】100. 相同的樹

一、題目 100. 相同的樹 - 力扣&#xff08;LeetCode&#xff09; 給你兩棵二叉樹的根節點 p 和 q &#xff0c;編寫一個函數來檢驗這兩棵樹是否相同。 如果兩個樹在結構上相同&#xff0c;并且節點具有相同的值&#xff0c;則認為它們是相同的。 二、思路 二叉樹的題&#…

C++的lambda函數、bind函數、類函數綁定參數,學習測試用例

在C中&#xff0c;Lambda函數、std::bind 和類函數綁定參數提供了靈活的方式來處理函數調用。 Lambda函數是一種匿名函數&#xff0c;可以捕獲外部變量并在函數體內使用。它們提供了簡潔而強大的方式來定義內聯函數。std::bind 用于創建一個新的函數對象&#xff0c;其中部分參…

2024電工杯數學建模B題高質量成品論文,包括代碼數據

2024電工杯數學建模B題高質量成品論文&#xff0c;包括代碼數據 完整內容見文末名片 摘要 大學時期是學生們知識學習和身體成長的重要階段&#xff0c;良好的飲食習慣對于促進生長發育和保證身體健康具有重要意義。針對當前大學生中存在的飲食結構不合理及不良飲食習慣的問題…

為了性能,放棄tft_eSPI,選擇arduino_gfx吧

本來對于tft_espi和arduino_gfx沒啥特別的感覺&#xff0c;都是tft屏幕驅動,arduino_gfx的好處就是除了支持tft外還支持一些oled屏幕。 誰知道在探尋我那個在單片機項目上顯示中文方案 https://github.com/StarCompute/tftziku 時候&#xff0c;尋求極致性能測了一些東西。 t…

23種設計模式之一————工廠模式詳細講解

工廠模式介紹 定義分類工廠模式核心角色&#xff1a;簡單工廠模式定義特點優點缺點應用場景代碼實現 工廠方法模式&#xff08;別名&#xff1a;虛擬構造&#xff09;定義特點優點缺點應用場景代碼實現 抽象工廠模式定義特點優點缺點應用場景代碼實現工廠模式小結 定義 工廠模…

算法之背包問題

可分的背包問題是可以用貪心法來解決&#xff0c;而0-1背包問題通常使用動態規劃方法來解決。 可分背包問題&#xff1a; 在可分背包問題中&#xff0c;物品可以被分割&#xff0c;您可以取走物品的一部分以適應背包的容量。這里的關鍵是物品的價值密度&#xff0c;即單…

最小產品價格差值

題目描述 給定某產品多少天的價格&#xff0c;記錄于prices中&#xff0c;請找出任意兩天之間的最小價格差&#xff08;即abs(prices[i] - prices[j])&#xff09;的最小值&#xff0c;i!j&#xff09;并計算最小介個差組合的個數 樣例1 輸入 [1,3,7,5,12] 輸出 3 樣例2…

VTK9.2.0+QT5.14.0繪制三維顯示背景

背景 上一篇繪制點云的博文中&#xff0c;使用的vtkCameraOrientationWidget來繪制的坐標軸&#xff0c;最近又學習到兩種新的坐標軸繪制形式。 vtkOrientationMarkerWidget vtkAxesActor 單獨使用vtkAxesActor能夠繪制出坐標軸&#xff0c;但是會隨著鼠標操作旋轉和平移時…

微服務中使用Maven BOM來管理你的版本依賴

摘要: 原創出處 sf.gg/a/1190000021198564 「飄渺Jam」歡迎轉載&#xff0c;保留摘要&#xff0c;謝謝&#xff01; 為什么要使用BOM? 如何定義BOM? 項目使用方法? BOM&#xff08;Bill of Materials&#xff09;是由Maven提供的功能,它通過定義一整套相互兼容的jar包版…

通過 NIO + 多線程 提升硬件設備與系統的數據傳輸性能

一、項目展示 下圖&#xff08;模擬的數據可視化大屏&#xff09;中數據是動態顯示的 二、項目簡介 描述&#xff1a;使用Client模擬了硬件設備&#xff0c;比如可燃氣體濃度檢測器。Client通過Socket與Server建立連接&#xff0c;Server保存數據到txt文件&#xff0c;并使用W…

結構體(位段)內存分配

結構體由多個數據類型的成員組成。那編譯器分配的內存是不是所有成員的字節數總和呢&#xff1f; 首先&#xff0c;stu的內存大小并不為29個字節&#xff0c;即證明結構體內存不是所有成員的字節數和。 ??其次&#xff0c;stu成員中sex的內存位置不在21&#xff0c;即可推測…

Swift 請求用戶授權以跟蹤其跨應用或網站的活動

步驟1:導入框架 首先,需要在Swift文件中導入AppTrackingTransparency框架。 import AppTrackingTransparency import AdSupport步驟2:請求跟蹤許可 在適當的地方請求用戶的跟蹤許可。通常,這個請求會在應用啟動時或者在用戶執行某些操作(例如,訪問應用中的廣告相關功能…

Linux服務器安裝docker,基于Linux(openEuler、CentOS8)

本實驗環境為openEuler系統(以server方式安裝)&#xff08;CentOS8基本一致&#xff0c;可參考本文) 目錄 知識點實驗 知識點 Docker 是一個開源的應用容器引擎。它允許開發者將應用及其所有依賴項打包到一個可移植的容器中&#xff0c;并發布到任何支持Docker的流行Linux或Wi…

基于python flask的web服務

基本例子 from flask import Flask app Flask(__name__) app.route(/)#檢查訪問的網址&#xff0c;根路徑走這里 def hello_world():return hello world#返回hello worldif __name__ __main__:# 綁定到指定的IP地址和端口app.run(host0.0.0.0, port1000, debugTrue)##綁定端…