JVM面試連環炮:你準備好迎接挑戰了嗎?

在Java開發領域,JVM面試一直是一個熱門話題。作為一名優秀的開發者,你是否已經準備好迎接這場挑戰了呢?今天,我們就來深度解析一下JVM面試的熱點問題,幫助你更好地應對面試,一舉拿下offer!

1、說一下 JVM 的主要組成部分及其作用?

在這里插入圖片描述

JVM包含兩個子系統和兩個組件,兩個子系統為Class loader(類裝載)、Execution engine(執行引擎);兩個組件為Runtime data area(運行時數據區)、Native Interface(本地接口)。

  • Class loader(類裝載):根據給定的全限定名類名(如:java.lang.Object)來裝載class文件到 Runtime data area中的method area。
  • Execution engine(執行引擎):執行classes中的指令。
  • Native Interface(本地接口):與native libraries交互,是其它編程語言交互的接口。
  • Runtime data area(運行時數據區域):這就是我們常說的JVM的內存。
作用:

在Java程序的執行過程中,首先會通過編譯器將Java源代碼轉換成一種叫做字節碼(Bytecode)的中間形式。這種字節碼是一種平臺無關的二進制代碼,它比Java源代碼更接近于機器語言,但仍然包含了一些用于定位和操作數據結構的指令。

然后,類加載器(ClassLoader)會負責將這種字節碼加載到內存中。這個過程通常是動態進行的,也就是說,當程序需要使用某個類的時候,類加載器就會將這個類的字節碼加載到內存中。這個過程通常發生在Java虛擬機(JVM)的運行時數據區(Runtime Data Area)的方法區內。

需要注意的是,雖然字節碼文件是JVM的一套指令集規范,但它并不能直接交給底層操作系統去執行。這是因為不同的操作系統可能對同一組字節碼有不同的解釋方式,因此需要一個專門的命令解析器執行引擎(Execution Engine)來將字節碼翻譯成底層系統可以執行的指令。

最后,Java程序中還可以調用其他語言編寫的本地庫接口(Native Interface),進行一些系統調用或者C函數調用。這種方式可以使Java程序更好地利用底層系統的功能,提高程序的性能和效率。

下面是ava程序運行機制詳細說明

Java程序運行機制步驟:

  • 首先利用IDE集成開發工具編寫Java源代碼,源文件的后綴為.java;
  • 再利用編譯器(javac命令)將源代碼編譯成字節碼文件,字節碼文件的后綴名為.class;
  • 運行字節碼的工作是由解釋器(java命令)來完成的。

在這里插入圖片描述

從上圖中可以觀察到,Java文件經過編譯器的處理后,被轉換成了對應的.class文件。接下來,類加載器會負責將這些.class文件加載到Java虛擬機(JVM)中。

實際上,類的加載過程可以用一句話來概括:類的加載是將類的二進制數據從.class文件中讀取出來,并將其放入內存中的運行時數據區的方法區內。然后,在堆區創建一個java.lang.Class對象,用于封裝類在方法區內的數據結構。

通過類加載器的作用,JVM能夠動態地加載和卸載類,使得程序可以在運行時動態地獲取和使用類。這種動態性是Java語言的一大特點,它賦予了程序更高的靈活性和擴展性。

2、說一下JVM運行時數據區?

Java虛擬機在執行Java程序的過程中,會將其管理的內存區域劃分為多個不同的數據區域。每個數據區域都有特定的用途,并且它們的創建和銷毀時間也不同。

首先,Java虛擬機將內存區域劃分為堆(Heap)、方法區(Method Area)和棧(Stack)。

  1. 堆:堆是Java虛擬機所管理的最大的數據區域。它用于存儲對象實例以及數組。當創建一個新的對象時,會在堆上分配相應的內存空間。而當一個對象不再被引用時,垃圾回收器會負責將其所占用的內存釋放回堆中。堆的大小可以通過JVM的參數進行設置,例如-Xmx和-Xms分別表示最大堆大小和初始堆大小。

  2. 方法區:方法區是用于存儲類信息、常量池、靜態變量等數據的一塊內存區域。它與Java類相關聯,因為每個Java類都包含方法區的一份拷貝。方法區的生命周期與Java虛擬機的生命周期一致,因此隨著虛擬機進程的啟動而存在。

  3. 棧:棧是Java虛擬機用來支持函數調用和方法執行的數據結構。每個線程在創建時都會創建一個獨立的棧,其中存儲著局部變量、操作數棧和返回地址等信息。棧的特點是后進先出(LIFO),即最后進入棧的元素會最先被取出。棧的生命周期與線程的生命周期一致,因此依賴于線程的啟動和結束來建立和銷毀。

除了這些主要的數據區域外,Java虛擬機還可能劃分其他一些輔助的區域,例如程序計數器(Program Counter Register)和本地方法棧(Native Method Stack)等。這些區域的具體用途和生命周期取決于Java虛擬機的實現和運行環境。

  • 程序計數器(Program Counter Register):當前線程所執行的字節碼的行號指示器,字節碼解析器的工作是通過改變這個計數器的值,來選取下一條需要執行的字節碼指令,分支、循環、跳轉、異常處理、線程恢復等基礎功能,都需要依賴這個計數器來完成;
  • 本地方法棧(Native Method Stack):與虛擬機棧的作用是一樣的,只不過虛擬機棧是服務 Java方法的,而本地方法棧是為虛擬機調用 Native 方法服務的;

image.png

3、什么是堆內存?

以Hotspot為例,堆內存(HEAP)主要由GC模塊進行分配和管理, 可分為以下部分:

  • 新生代(伊甸園區+幸存者區)
  • 老年代

我們在jvm參數中只要使用-Xms,-Xmx等參數就可以設置堆的大小和最大值,理解jvm的堆還需要知道下面這個公式:
堆內內存 = 新生代+老年代。如下面的圖所示:

image.png

在使用堆內內存(on-heap memory)的時候,完全遵守JVM虛擬機的內存管理機制,采用垃圾回收器(GC)統一進行內存管理,GC會在某些特定的時間點進行一次徹底回收,也就是Full GC,GC會對所有分配的堆內內存進行掃描,在這個過程中會對JAVA應用程序的性能造成一定影響,還可能會產生Stop The World。
常見的垃圾回收算法主要有:

  • 引用計數器法(Reference Counting)
  • 標記清除法(Mark-Sweep)
  • 復制算法(Coping)
  • 標記壓縮法(Mark-Compact)
  • 分代算法(Generational Collecting)

4、什么是堆外內存?

堆外內存,也常被稱為直接內存,是Java虛擬機管理內存的一種方式。與Java虛擬機的堆內存相對應,堆外內存是將內存對象分配在Java虛擬機的堆以外的內存區域。這部分內存并不受Java虛擬機的管理,而是直接由操作系統進行操作和管理。

這種設計的主要優點是能夠在一定程度上減少垃圾回收對應用程序造成的影響。因為堆外內存的分配和釋放不依賴于Java虛擬機的垃圾回收機制,所以它可以更快速地進行內存的分配和釋放,從而提高應用程序的性能。

作為Java開發者,我們經常使用java.nio.DirectByteBuffer類來管理堆外內存。這個類的實例會在對象創建的時候自動分配堆外內存。DirectByteBuffer類提供了一種在Java堆外分配內存的方式,它主要是通過其成員變量unsafe來進行操作的。

5、使用堆外內存的優點

  • 減少了垃圾回收, 因為垃圾回收會暫停其他的工作。
  • 加快了復制的速度,堆內在flush到遠程時,會先復制到直接內存(非堆內存),然后在發送;而堆外內存相當于省略掉了這個工作。

6、簡述Java垃圾回收機制

在Java編程中,程序員并不需要顯式地釋放對象的內存,這是由Java虛擬機(JVM)自動完成的。當一個對象不再被任何變量引用時,它就會被視為“垃圾”,并被標記為可回收的內存。然后,JVM會定期運行垃圾回收線程來檢查這些垃圾對象,并將它們從內存中清除。

這個垃圾回收線程在JVM中的優先級是低的,這意味著它不會在程序運行過程中頻繁地執行。相反,它會在JVM認為合適的時候執行。例如,當JVM的空閑時間超過一定閾值時,或者當堆內存的使用率達到一定限制時,垃圾回收線程就會被觸發。

垃圾回收線程的工作過程是這樣的:首先,它會掃描所有的對象,找出那些沒有被任何其他變量引用的對象。這些對象就被稱為“垃圾”。然后,它將這些垃圾對象添加到一個稱為“垃圾回收集合”的數據結構中。最后,它會從內存中徹底清除這些垃圾對象,釋放它們占用的內存空間。

總的來說,Java程序員不需要擔心內存管理問題,因為JVM會自動處理這些問題。這大大簡化了編程的復雜性,使得程序員可以更專注于實現具體的功能,而不是管理內存。

7、哪些對象會被存放到老年代?

  • 新生代對象每次經歷?次minor gc,年齡會加1,當達到年齡閾值(默認為15歲)會直接進?老年代;
  • 大對象直接進?老年代;
  • 新生代復制算法需要?個survivor區進行輪換備份,如果出現大量對象在minor gc后仍然存活的情況時,就需要老年代進行分配擔保,讓survivor?法容納的對象直接進?老年代;
  • 如果在Survivor空間中相同年齡所有對象大?的總和大于Survivor空間的?半,年齡大于或等于該年齡的對象就可以直接進?年?代。

8、什么時候觸發full gc?

  • 調用System.gc時,系統建議執行Full GC,但是不必然執行
  • 老年代空間不?
  • 方法區空間不?
  • 通過Minor GC后進入老年代的平均大小大于老年代的可用內存
  • 由Eden區、From Space區向To Space區復制時,對象大小大于To Space可用內存,則把該對象轉存到老年代,且老年代的可用內存小于該對象大小

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

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

相關文章

Python 使用sphinx生成API文檔

目錄 前言: 項目層級 Python項目docstring規范 Example Google Style Python Docstrings Example NumPy Style Python Docstrings reStructuredText Style 設置代碼docstrings風格(pycharm) 安裝sphinx 創建sphinx文檔項目 配置conf.py文件 編譯代碼為api文檔 編譯…

vim + ctags 跳轉, 查看函數定義

yum install ctags Package ctags-5.8-13.el7.x86_64 already installed and latest version 創建 /home/mzh/pptp-master/tags.sh #!/usr/bin/shWORKDIR/home/mzh/pptp-masterfind ${WORKDIR} -name "*.[c|h]" | xargs ctags -f ${WORKDIR}/tags find /usr/inclu…

final的安全發布

final的安全發布 兩個關鍵字“發布”“安全” 所謂發布通俗一點的理解就是創建一個對象,使這個對象能被當前范圍之外的代碼所使用 比如Object o new Object(); 然后接下來使用對象o 但是對于普通變量的創建,之前分析過,大致分為三個步驟&am…

k8s之身份認證與權限

Kubernetes 中提供了良好的多租戶認證管理機制,如 RBAC、ServiceAccount 還有各種策略等。 通過該文件可以看到已經配置了 RBAC 訪問控制 /usr/lib/systemd/system/kube-apiserver.service 1.1 認證 所有 Kubernetes 集群有兩類用戶:由 Kubernetes 管理的…

mysql數據庫學習筆記(1)

今天開始學mysql數據庫,為什么要學這個呢,因為數據庫可結構化存儲大量的數據信息,方便用戶進行有效的檢索和訪問。數據庫可有效地保持數據信息的一致性、完整性、降低數據冗余。數據庫可滿足應用的共享和安全方面的要求,把數據放在…

java--認識異常、自定義異常

1.異常體系 Error:代表的系統級別錯誤(屬于嚴重問題),也就是說系統一旦出現問題,sun公司會把這些問題封裝成Error對象給出來,說白了,Error是給sun公司自己用的,不是給我們程序員用的,因此我們開…

MacOS下homebrew的安裝與使用

安裝Homebrew //刪除原來的文件,可以在刪除前查看下Cellar文件夾下已安裝的包,homebrew將工具安裝在這個文件夾下,并在/usr/local/bin下建立連接 sudo -irm -rf /usr/local/Cellar /usr/local/.gi sudo chown -R liudong /usr/local //更新文件屬主為liu…

114. 二叉樹展開為鏈表 --力扣 --JAVA

題目 給你二叉樹的根結點 root ,請你將它展開為一個單鏈表: 展開后的單鏈表應該同樣使用 TreeNode ,其中 right 子指針指向鏈表中下一個結點,而左子指針始終為 null 。展開后的單鏈表應該與二叉樹 先序遍歷 順序相同。 解題思路 …

通過Ai幫我們寫前端界面設計

現在我要寫一個前端界面,from表單,讓用戶登錄使用的,提交表單之前先分析用戶名和密碼是否填的完成,并且檢查密碼必須滿足 包含大小寫,數字,密碼長度必須在8到20之間,不滿足不可以提交。用戶名必…

ethtool

ethtool ethtool是一個常用的命令行工具,用于配置和查詢以太網接口的驅動程序和硬件參數。它提供了一種簡單的方式來檢查和修改網絡接口的設置,以及獲取與以太網接口相關的統計數據和狀態信息。 ethtool可以執行以下常見的操作: 查詢接口信息…

【Hadoop】修改YARN配置文件

本節需要修改的 YARN 配置文件保存在$HADOOP_HOME/etc/haoop 目錄下,需要修改的文件共有 7 個,分別是:core-site.xml, hadoop-env.sh, hdfs-site.xml, yarn-site.xml, yarn-env.sh, mapred-site.xml, slave. 這些文件的用途: core…

Mysql:慢cpu過高慢sql查詢方法

通過 processlist查詢較為便捷,只是結果的info中只會顯示sql的前100個字符。 show processlist 通過下面語句查詢可顯示當前正在執行的完整sql。 SELECT * FROM information_schema.processlist WHERE COMMAND ‘Query’; 借助navicate數據庫工具的監控功能查詢庫的…

大數據技術2:大數據處理流程

前言:下圖是一個簡化的大數據處理流程圖,大數據處理的主要流程包括數據收集、數據存儲、數據處理、數據應用等主要環節。 1.1 數據收集 大數據處理的第一步是數據的收集。現在的中大型項目通常采用微服務架構進行分布式部署,所以數據的采集需…

【常用字符大全】含emoji表情

常用符號大全 ?????????????▲???↑↓◆◇⊙■□△▽─│??♂♀?????????▼???≈←→?◎☉★☆⊿※¡━┃??ツ?????©?Σ????卐√↖↗●?Θ◤◥︻〖〗┄┆℃℉?????¢€£∞?★?↙↘○?⊕◣◢︼【】┅┇…

Java 中適合使用隊列(Queue)的場景

在 Java 中,隊列(Queue)適合用于以下場景: 先進先出(FIFO)數據處理:當需要按照數據的添加順序進行處理時,可以使用隊列。例如,處理任務隊列、消息隊列等。 示例&#xff…

MySQL慢SQL優化思路

MySQL慢SQL優化思路 具體思路: 1、慢查詢日志記錄慢 SQL 2、explain 分析 SQL 的執行計劃 3、profile 分析執行耗時 4、Optimizer Trace 分析詳情 5、確定問題并采用相應的措施 1、查看慢日志 1.1 使用命令查詢慢日志配置 mysql> show variables like s…

mysql 5.7.34升級到5.7.44修補漏洞

mysql 5.7.34舊版本,漏掃有漏洞,升級到最新版本 舊版本5.7.34在 /home/mysql/mysql中安裝 備份舊版本數據還有目錄 數據庫備份升級 tar -xf mysql-5.7.44-el7-x86_64.tar #覆蓋舊版本數據庫文件 #注意看看文件是否和你起服務的用戶一樣 \cp -r mysql-5…

decomposition-based multi-objective algorithm4SPDPTW

關鍵詞 文章概述 研究背景 多目標選擇性接送和配送問題(PDPs):研究涉及多目標選擇性接送和配送問題,這些問題傳統上從單一目標角度進行探討,以尋找最具盈利性的請求集合,同時遵守一系列限制條件。 經濟和…

基于OpenCV+CNN+IOT+微信小程序智能果實采摘指導系統——深度學習算法應用(含python、JS工程源碼)+數據集+模型(五)

目錄 前言總體設計系統整體結構圖系統流程圖 運行環境Python環境TensorFlow 環境Jupyter Notebook環境Pycharm 環境微信開發者工具OneNET云平臺 模塊實現1. 數據預處理2. 創建模型并編譯3. 模型訓練及保存4. 上傳結果5. 小程序開發1)查詢圖片2)查詢識別結…

?os.path --- 常用路徑操作?

源代碼: Lib/posixpath.py (用于 POSIX) 和 Lib/ntpath.py (用于 Windows)。 此模塊實現了一些有用的路徑名稱相關函數。 要讀取或寫入文件請參見 open(),對于訪問文件系統請參閱 os 模塊。 傳給 path 形參的可以是字符串、字節串或者任何實現了 os.PathLike 協議的…