JVM相關面試題(2024大廠高頻面試題系列)

一、JVM的組成

1、JVM由哪些部分組成,運行流程是什么?
在這里插入圖片描述

回答:在JVM中共有四大部分,分別是Class Loader(類加載器)、Runtime Data Area(運行時數據區,內存分區)、Execution Engine(執行引擎)、Native Method Library(本地庫接口)。

它們的運行流程是:
第一,類加載器(ClassLoader)把Java代碼轉換為字節碼文件
第二,運行時數據區(Runtime Data Area)把字節碼加載到內存中,而字節
碼文件只是JVM的一套指令集規范,并不能直接交給底層系統去執行,而是
有執行引擎運行
第三,執行引擎(Execution Engine)將字節碼翻譯為底層系統指令,再交
由CPU執行去執行,此時需要調用其他語言的本地庫接口(Native Method
Library)來實現整個程序的功能。

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

運行時數據區包含了堆、方法區、棧、本地方法棧、程序計數器這幾部分,每個功能作用不一樣。

堆解決的是對象實例存儲的問題,垃圾回收器管理的主要區域。

方法區可以認為是堆的一部分,用于存儲已被虛擬機加載的信息,常量、靜態變量、即時編譯器編譯后的代碼。

棧解決的是程序運行的問題,棧里面存的是棧幀,棧幀里面存的是局部變量表、操作數棧、動態鏈接、方法出口等信息。

本地方法棧與棧功能相同,本地方法棧執行的是本地方法,一個Java調用非Java代碼的接口。

程序計數器(PC寄存器)程序計數器中存放的是當前線程所執行的字節碼的行數。JVM工作時就是通過改變這個計數器的值來選取下一個需要執行的字節碼指令。

3、你再詳細介紹一下程序計數器的作用?

java虛擬機對于多線程是通過線程輪流切換并且分配線程執行時間。在任何的一個時間點上,一個處理器只會處理執行一個線程,如果當前被執行的這個線程它所分配的執行時間用完了【掛起】。處理器會切換到另外的一個線程上來進行執行。并且這個線程的執行時間用完了,接著處理器就會又來執行被掛起的這個線程。這時候程序計數器就起到了關鍵作用,程序計數器在來回切換的線程中記錄他上一次執行的行號,然后接著繼續向下執行。

4、你能給我詳細的介紹Java堆嗎?
在這里插入圖片描述

Java中的堆術語線程共享的區域。主要用來保存對象實例,數組等,當堆中沒有內存空間可分配給實例,也無法再擴展時,則拋出OutOfMemoryError異常。

在JAVA8中堆內會存在年輕代、老年代

1)Young區被劃分為三部分,Eden區和兩個大小嚴格相同的Survivor區,其中,Survivor區間中,某一時刻只有其中一個是被使用的,另外一個留做垃圾收集時復制對象用。在Eden區變滿的時候, GC就會將存活的對象移到空閑的Survivor區間中,根據JVM的策略,在經過幾次垃圾收集后,任然存活于Survivor的對象將被移動到Tenured區間。

2)Tenured區主要保存生命周期長的對象,一般是一些老的對象,當一些
對象在Young復制轉移一定的次數以后,對象就會被轉移到Tenured區。

5、能不能解釋一下方法區?

與虛擬機棧類似。本地方法棧是為虛擬機執行本地方法時提供服務的。不需要進行GC。本地方法一般是由其他語言編寫。

6、聽過直接內存嗎?

它又叫做堆外內存,線程共享的區域,在 Java 8 之前有個永久代的概念,實際上指的是 HotSpot 虛擬機上的永久代,它用永久代實現了 JVM 規范定義的方法區功能,主要存儲類的信息,常量,靜態變量,即時編譯器編譯后代碼等,這部分由于是在堆中實現的,受 GC 的管理,不過由于永久代有 -XX:MaxPermSize 的上限,所以如果大量動態生成類(將類信息放入永久代),很容易造成 OOM,有人說可以把永久代設置得足夠大,但很難確定一個合適的大小,受類數量,常量數量的多少影響很大。所以在 Java 8 中就把方法區的實現移到了本地內存中的元空間中,這樣方法區就不受 JVM 的控制了,也就不會進行 GC,也因此提升了性能。

7、什么是虛擬機棧

虛擬機棧是描述的是方法執行時的內存模型,是線程私有的,生命周期與線程相同,每個方法被執行的同時會創建棧楨。保存執行方法時的局部變量、動態連接信息、方法返回地址信息等等。方法開始執行的時候會進棧,方法執行完會出棧【相當于清空了數據】,所以這塊區域不需要進行 GC。

8、能說一下堆棧的區別是什么嗎?

第一,棧內存一般會用來存儲局部變量和方法調用,但堆內存是用來存儲
Java對象和數組的的。堆會GC垃圾回收,而棧不會。
第二、棧內存是線程私有的,而堆內存是線程共有的。
第三、兩者異常錯誤不同,但如果棧內存或者堆內存不足都會拋出異常。
棧空間不足:java.lang.StackOverFlowError。
堆空間不足:java.lang.OutOfMemoryError。

二、類加載器

1、什么是類加載器,類加載器有哪些?

JVM只會運行二進制文件,而類加載器(ClassLoader)的主要作用就是將字節碼文件加載到JVM中,從而讓Java程序能夠啟動起來。

常見的類加載器有4個:

第一個是啟動類加載器(BootStrap ClassLoader):其是由C++編寫實現。用于加載JAVA_HOME/jre/lib目錄下的類庫。

第二個是擴展類加載器(ExtClassLoader):該類是ClassLoader的子類,主要加載JAVA_HOME/jre/lib/ext目錄中的類庫。

第三個是應用類加載器(AppClassLoader):該類是ClassLoader的子類,主要用于加載classPath下的類,也就是加載開發者自己編寫的Java類。

第四個是自定義類加載器:開發者自定義類繼承ClassLoader,實現自定義類加載規則。

2、說一下類裝載的執行過程?

類從加載到虛擬機中開始,直到卸載為止,它的整個生命周期包括了:加載、驗證、準備、解析、初始化、使用和卸載這7個階段。其中,驗證、準備和解析這三個部分統稱為連接(linking)

1.加載:查找和導入class文件
2.驗證:保證加載類的準確性
3.準備:為類變量分配內存并設置類變量初始值
4.解析:把類中的符號引用轉換為直接引用
5.初始化:對類的靜態變量,靜態代碼塊執行初始化操作
6.使用:JVM 開始從入口方法開始執行用戶的程序代碼
7.卸載:當用戶程序代碼執行完畢后,JVM 便開始銷毀創建的 Class 對象,最后負責運行的 JVM 也退出內存

3、什么是雙親委派模型?

如果一個類加載器收到了類加載的請求,它首先不會自己嘗試加載這個類,而是把這請求委派給父類加載器去完成,每一個層次的類加載器都是如此,因此所有的加載請求最終都應該傳說到頂層的啟動類加載器中,只有當父類加載器返回自己無法完成這個加載請求(它的搜索返回中沒有找到所需的類)時,子類加載器才會嘗試自己去加載。

4、JVM為什么采用雙親委派機制

主要有兩個原因。
第一、通過雙親委派機制可以避免某一個類被重復加載,當父類已經加載后則無需重復加載,保證唯一性。

第二、為了安全,保證類庫API不會被修改

三、 垃圾回收

1、簡述Java垃圾回收機制?(GC是什么?為什么要GC)

為了讓程序員更專注于代碼的實現,而不用過多的考慮內存釋放的問題,所以,在Java語言中,有了自動的垃圾回收機制,也就是我們熟悉的GC(Garbage Collection)。

有了垃圾回收機制后,程序員只需要關心內存的申請即可,內存的釋放由系統自動識別完成。在進行垃圾回收時,不同的對象引用類型,GC會采用不同的回收時機。

2、強引用、軟引用、弱引用、虛引用的區別?

強引用最為普通的引用方式,表示一個對象處于有用且必須的狀態,如果一個對象具有強引用,則GC并不會回收它。即便堆中內存不足了,寧可出現OOM,也不會對其進行回收

軟引用表示一個對象處于有用且非必須狀態,如果一個對象處于軟引用,在內存空間足夠的情況下,GC機制并不會回收它,而在內存空間不足時,則會在OOM異常出現之間對其進行回收。但值得注意的是,因為GC線程優先級較低,軟引用并不會立即被回收。

弱引用表示一個對象處于可能有用且非必須的狀態。在GC線程掃描內存區域時,一旦發現弱引用,就會回收到弱引用相關聯的對象。對于弱引用的回收,無關內存區域是否足夠,一旦發現則會被回收。同樣的,因為GC線程優先級較低,所以弱引用也并不是會被立刻回收。

虛引用表示一個對象處于無用的狀態。在任何時候都有可能被垃圾回收。虛引用的使用必須和引用隊列Reference Queue聯合使用。

3、對象什么時候可以被垃圾器回收

如果一個或多個對象沒有任何的引用指向它了,那么這個對象現在就是垃圾,如果定位了垃圾,則有可能會被垃圾回收器回收。

如果要定位什么是垃圾,有兩種方式來確定,第一個是引用計數法,第二個是可達性分析算法。通常都使用可達性分析算法來確定是不是垃圾。

4、JVM 垃圾回收算法有哪些?

我記得一共有四種,分別是標記清除算法、復制算法、標記整理算法、分代回收。

5、你能詳細聊一下分代回收嗎?

關于分代回收是這樣的

在java8時,堆被分為了兩份:新生代和老年代,它們默認空間占用比例是1:2
對于新生代,內部又被分為了三個區域。Eden區,S0區,S1區默認空間占用比例是8:1:1

具體的工作機制是有些情況:
1)當創建一個對象的時候,那么這個對象會被分配在新生代的Eden區。當Eden區要滿了時候,觸發YoungGC。
2)當進行YoungGC后,此時在Eden區存活的對象被移動到S0區,并且當前對象的年齡會加1,清空Eden區。
3)當再一次觸發YoungGC的時候,會把Eden區中存活下來的對象和S0中的對象,移動到S1區中,這些對象的年齡會加1,清空Eden區和S0區。
4)當再一次觸發YoungGC的時候,會把Eden區中存活下來的對象和S1中的對象,移動到S0區中,這些對象的年齡會加1,清空Eden區和S1區。
5)對象的年齡達到了某一個限定的值(默認15歲 ),那么這個對象就會進入到老年代中。當然也有特殊情況,如果進入Eden區的是一個大對象,在觸發YoungGC的時候,會直接存放到老年代,當老年代滿了之后,觸發FullGC。FullGC同時回收新生代和老年代,當前只會存在一個FullGC的線程進行執行,其他的線程全部會被掛起。 我們在程序中要盡量避免FullGC的出現。

6、講一下新生代、老年代、永久代的區別?

新生代主要用來存放新生的對象。

老年代主要存放應用中生命周期長的內存對象。

永久代指的是永久保存區域。主要存放Class和Meta(元數據)的信息。在Java8中,永久代已經被移除,取而代之的是一個稱之為“元數據區”(元空間)的區域。元空間和永久代類似,不過元空間與永久代之間最大的區別在于:元空間并不在虛擬機中,而是使用本地內存。因此,默認情況下,元空間的大小僅受本地內存的限制。

7、說一下 JVM 有哪些垃圾回收器?

在jvm中,實現了多種垃圾收集器,包括:串行垃圾收集器、并行垃圾收集器(JDK8默認)、CMS(并發)垃圾收集器、G1垃圾收集器(JDK9默認)

8、Minor GC、Major GC、Full GC是什么

它們指的是不同代之間的垃圾回收
Minor GC 發生在新生代的垃圾回收,暫停時間短
Major GC 老年代區域的垃圾回收,老年代空間不足時,會先嘗試觸發MinorGC。Minor GC之后空間還不足,則會觸發Major GC,Major GC速度較慢,暫停時間長
Full GC 新生代 + 老年代完整垃圾回收,暫停時間長,應盡力避免

四、JVM實踐調優

1、JVM 調優的參數可以在哪里設置參數值?

springboot項目可以在項目啟動的時候,java -jar中加入參數就行了

2、用的 JVM 調優的參數都有哪些?

?-Xms2g:初始化推大小為 2g;
?-Xmx2g:堆最大內存為 2g;
?-XX:NewRatio=4:設置年輕的和老年代的內存比例為 1:4;
?-XX:SurvivorRatio=8:設置新生代 Eden 和 Survivor 比例為 8:2;
?–XX:+UseParNewGC:指定使用 ParNew + Serial Old 垃圾回收器組合;
?-XX:+UseParallelOldGC:指定使用 ParNew + ParNew Old 垃圾回收器組合;
?-XX:+UseConcMarkSweepGC:指定使用 CMS + Serial Old 垃圾回收器組合;
?-XX:+PrintGC:開啟打印 gc 信息;
?-XX:+PrintGCDetails:打印 gc 詳細信息。

3、平時調試 JVM都用了哪些工具呢?
一般都是使用jdk自帶的一些工具,比如
jps 輸出JVM中運行的進程狀態信息
jstack查看java進程內線程的堆棧信息
jmap 用于生成堆轉存快照
jstat用于JVM統計監測工具
還有一些可視化工具,像jconsole和VisualVM等

4、假如項目中產生了java內存泄露,你說一下你的排查思路?

第一呢可以通過jmap指定打印他的內存快照 dump文件,不過有的情況打印不了,我們會設置vm參數讓程序自動生成dump文件
第二,可以通過工具去分析 dump文件,jdk自帶的VisualVM就可以分析
第三,通過查看堆信息的情況,可以大概定位內存溢出是哪行代碼出了問題
第四,找到對應的代碼,通過閱讀上下文的情況,進行修復即可

5、服務器CPU持續飆高,你的排查方案與思路?

第一可以使用使用top命令查看占用cpu的情況

第二通過top命令查看后,可以查看是哪一個進程占用cpu較高,記錄這個進程id

第三可以通過ps 查看當前進程中的線程信息,看看哪個線程的cpu占用較高

第四可以jstack命令打印進行的id,找到這個線程,就可以進一步定位問題代碼的行號

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

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

相關文章

MyBatis的補充用法

說明:之前介紹過MyBatis的用法,像 用注解和Mapper.xml操作數據庫、在Mapper.xml里寫動態SQL。最近在一次用MyBatis批量更新數據庫對象的場景中,意識到對MyBatis的一些標簽用法不太熟悉,所以去 MyBatis官網 看了一些文檔&#xff0…

php httpfs鏈接hdfs

一.代碼(有bug) GitHub - michaelbutler/php-WebHDFS: A PHP client for WebHDFS 二.調用代碼 1.代碼1.代碼 require_once(../webhdfs/src/org/apache/hadoop/WebHDFS.php);require_once(../webhdfs/src/org/apache/hadoop/tools/Curl.php); require_o…

什么是人才儲備?如何做人才儲備?

很多小伙伴都會有企業面試被拒的情況,然后HR會告訴你,雖然沒有錄用你,但是你進入了他們的人才儲備庫,那么這個儲備庫有什么作用和特點呢?我們如何應用人才測評系統完善人才儲備庫呢? 人才儲備一般有以下三…

Python打發無聊時光:12.用PyQt實現簡易的心電起搏器界面

第一步:裝PyQt庫 pip install PyQt5 第二步:復制代碼 import sys from PyQt5.QtWidgets import (QApplication, QMainWindow, QPushButton, QVBoxLayout,QWidget, QLabel, QProgressBar, QSlider, QLineEdit, QHBoxLayout) from PyQt5.QtCore import …

軟件分層(數據結構/軟件邏輯上分層+舉例),相連節點的概念+如何相連,為什么是層狀結構(軟件分層,網絡協議分層+梳理協議順序),協議分層(打電話例子)

目錄 軟件分層 介紹 舉例 類的繼承 虛擬文件系統 線程接口封裝 虛擬地址空間 總結 為什么是層狀的 軟件分層 網絡協議 原因 梳理協議順序 相連節點 協議分層 引入 示例 實際上 邏輯上 制定出協議 軟件分層 介紹 通過將軟件系統劃分為不同的層次,每一層都有…

uniApp 調整小程序 單個/全部界面橫屏展示效果

我們打開uni項目 小程序端運行 默認是豎著的一個效果 我們打開項目的 pages.json 給需要橫屏的界面 的 style 屬性 加上 "mp-weixin": {"pageOrientation": "landscape" }界面就橫屏了 如果是要所有界面都橫屏的話 就直接在pages.json 的 gl…

Ps:海綿工具

海綿工具 Sponge Tool可用于調整圖像中特定區域的飽和度,常用于增加或減少顏色的飽和度。 快捷鍵:O 在特別的灰度圖像上,則可用于調整對比度,這可以開發出更多的創意技巧。 ◆ ◆ ◆ 常用操作方法與技巧 1、海綿工具主要用于調整…

源碼解析篇 | YOLOv8官方源碼項目目錄結構解析

前言:Hello大家好,我是小哥談。YOLOv8是一種目標檢測算法,它是YOLO(You Only Look Once)系列算法的第8個版本。YOLOv8相比于之前的版本,在檢測精度和速度上都有所提升,它在各種場景下都表現出色…

Git源碼管理

參考視頻:16-git的日志以及版本管理_嗶哩嗶哩_bilibili 參考博客:Git && Docker 學習筆記-CSDN博客 目錄 簡介 個人操作初始化 初始化git目錄 查看生成的git目錄文件 配置git工作目錄的用戶信息 查看工作區的狀態,生成文件的…

【JS】生成N位隨機數

作用 用于郵箱驗證碼 碼 ramNum.js /*** 生成N位隨機數字* param {Number} l 默認&#xff1a;6&#xff0c;默認生成6位隨機數字* returns 返回N位隨機數字*/ const ramNum (l 6) > {let num for (let i 0; i < l; i) {const n Math.random()const str String(n…

C++面試干貨---帶你梳理常考的面試題(一)

顧得泉&#xff1a;個人主頁 個人專欄&#xff1a;《Linux操作系統》 《C從入門到精通》 《LeedCode刷題》 鍵盤敲爛&#xff0c;年薪百萬&#xff01; 1.C和C的區別 1.語法和特性&#xff1a;C是一種過程式編程語言&#xff0c;而C是一種面向對象編程語言。C在C的基礎上增加…

Java智慧云HIS醫院信息化系統源碼 更具靈活性、擴展性

目錄 什么是云HIS 趨勢與轉變 HIS上云后有哪些好處 解決方案 云HIS組成 1、門診掛號 2、住院管理 3、電子病歷 4、藥物管理 5、統計報表 6、綜合維護 7、運營運維 什么是云HIS 云HIS是一種基于云計算技術的醫院信息管理系統。云HIS可以幫助醫院管理各類醫院信息&a…

CIE-Alevel-Physics分類真題下載(更新中)

鏈接真題歸類年份https://www.savemyexams.com/https://gceguide.com/papershttps://pastpapers.papacambridge.com/https://rocketrevise.comhttps://www.exam-mate.com/markhint.inhttps://xtremepape.rs/threads/as-and-a-level-physics-topical-pastpapers-upto-2015-with-…

Java Linux基本命令面試題

Java Linux基本命令面試題 前言1、查看文件內容有哪些命令可以使用&#xff1f;2、終端是哪個文件夾下的哪個文件&#xff1f;黑洞文件是哪個文件夾下的哪個命令&#xff1f;3、用什么命令對一個文件的內容進行統計&#xff1f;(行號、單詞數、字節數)4、怎么使一個命令在后臺運…

每日OJ題_分治歸并②_力扣LCR 170. 交易逆序對的總數

目錄 力扣LCR 170. 交易逆序對的總數 解析代碼1 解析代碼2 力扣LCR 170. 交易逆序對的總數 LCR 170. 交易逆序對的總數 難度 困難 在股票交易中&#xff0c;如果前一天的股價高于后一天的股價&#xff0c;則可以認為存在一個「交易逆序對」。請設計一個程序&#xff0c;輸…

Linux系統中安裝redis+redis后臺啟動+常見相關配置

1、下載Redis Redis官網&#xff1a;https://redis.io/ 歷史版本&#xff1a; http://download.redis.io/releases 2、連接Linux&#xff08;或者VMwear&#xff09; 我們安裝的是linux版本的redis 打開xftp我們需要先將我們的Redis上傳到服務器上 解壓到這里 解壓的指令 …

創建型模式之建造者模式

一、概述 1、建造者模式&#xff1a;將一個復雜對象的構建和它的表示分離&#xff0c;使得同樣的構建過程可以創建不同的表示 2、將客戶端與包含多個部件的復雜對象的創建過程分離&#xff0c;客戶端無須知道復雜對象的內部組成部分與裝配方式&#xff0c;只需要知道所需建造…

Spring MVC源碼中設計模式——適配器模式

適配器模式介紹 適配器模式&#xff08;Adapter Pattern&#xff09;是作為兩個不兼容的接口之間的橋梁。這種類型的設計模式屬于結構型模式&#xff0c;它結合了兩個獨立接口的功能。 應用場景&#xff1a; 1、系統需要使用現有的類&#xff0c;而此類的接口不符合系統的需要…

[c++] 繼承和多態整理一

1 private 和 protected 繼承&#xff0c;子類指針不能賦值給父類指針 如下代碼&#xff0c;有一個基類 Base&#xff0c;Derived1&#xff0c;Derived2&#xff0c;Derived3 3 個子類繼承了基類 Base&#xff0c;分別是 private 繼承&#xff0c;protected 繼承&#xff0c;p…

基于springboot+vue的紡織品企業財務管理系統

博主主頁&#xff1a;貓頭鷹源碼 博主簡介&#xff1a;Java領域優質創作者、CSDN博客專家、阿里云專家博主、公司架構師、全網粉絲5萬、專注Java技術領域和畢業設計項目實戰&#xff0c;歡迎高校老師\講師\同行交流合作 ?主要內容&#xff1a;畢業設計(Javaweb項目|小程序|Pyt…