1. 程式人生 > >Java 虛擬機器面試題

Java 虛擬機器面試題

如果物件的引用被置為null,垃圾收集器是否會立即釋放物件佔用的記憶體?

不會,在下一個垃圾回收週期中,這個物件將是可被回收的。

也就是說當一個物件的引用變為 null 時,並不會被垃圾收集器立刻回收,而是在下一次垃圾回收時才會釋放其佔用的記憶體。

finalize()方法工作原理

一旦垃圾回收器準備好釋放物件佔用的儲存空間,將首先呼叫其 finalize() 方法(如果如果覆蓋了finalize()),並且在下一次垃圾回收動作發生時,才會真正回收物件佔用的記憶體。

至於為什麼在下一次垃圾回收動作發生時才會回收記憶體,原因是如果一個物件覆蓋了 finalize() 方法,那麼在真正被宣告死亡的時候,至少需要經過兩次標記。第一次被標記的時候會被放在 一個 F-Queue

佇列中,finalize() 方法是物件逃脫死亡命運的最後一次機會。在第二次標記的時候,如果該物件成功與引用鏈(GC-Roots)上的任何一個物件關聯,那麼它仍然可以存活下來,否則將會被垃圾收集器回收。

Java 8 的記憶體分代改進

在 jdk1.8 中對記憶體模型中方法區的實現永久代(Perm Gen space)進行了移除,取而代之的是元空間(Metaspace)。

原因是在方法區中實現垃圾回收的條件比較苛刻,因此存在著記憶體溢位的風險。在 jdk1.8 之後,當方法區記憶體使用較多時,元空間會使用實體記憶體,減少了風險。如下
這裡寫圖片描述

分別寫出堆記憶體溢位與棧記憶體溢位的程式

棧記憶體溢位

    public void f() {
        f();
    }

堆記憶體溢位

    public void testd() {
        List<String> list = new ArrayList<>();
        int i = 0;

        while (true) {
            list.add(new String(i + ""));
            i++;
        }
    }
反射中,Class.forName()ClassLoader.loadClass()
區別

雖然問到的是反射,但是在底層涉及到了虛擬機器的類載入知識,只有瞭解了虛擬機器的類載入過程,才能更好地理解這個題目
這裡寫圖片描述

  • 載入:載入 class 的二進位制流,將位元組流儲存結構轉化為方法區執行的資料結構,生成一個 Class 物件作為這個類的訪問入口
  • 驗證:保證 class 檔案的位元組流中包含的資訊符合虛擬機器的要求,比如檔案格式驗證,元資料驗證等
  • 準備:為類變數分配記憶體,並設定初始值,並非在堆中分配記憶體,而是在方法區
  • 解析:將常量池中的符號引用替換為直接引用
  • 初始化:也是類載入的最後一步,執行類構造器 clinit() 方法,按照要求初始化靜態變數的值,並執行靜態程式碼塊

下面是 Class.forName()ClassLoader的區別

  • Class.forName() 預設執行類載入過程中的連線與初始化動作,一旦執行初始化動作,靜態變數就會被初始化為程式設計師設定的值,如果有靜態程式碼塊,靜態程式碼塊也會被執行
  • ClassLoader.loadClass() 預設只執行類載入過程中的載入動作,後面的動作都不會執行

比如我們連線 MySQL 資料庫會用到的 Class.forName("com.mysql.cj.jdbc.Driver"),在類載入的過程中就會通過靜態程式碼塊註冊一個驅動物件。

    static {
        try {
            java.sql.DriverManager.registerDriver(new Driver());
        } catch (SQLException E) {
            throw new RuntimeException("Can't register driver!");
        }
    }
說說強引用、軟引用、弱引用、虛引用以及他們之間和 gc 的關係
  • 強引用是指在程式碼中普遍存在的,類似 Object obj = new Object(); 這類的引用,只要強引用還存在,垃圾回收器永遠不會回收掉引用的物件
  • 軟引用是用來描述一些還有用但並非是必要的物件。對於軟引用著的物件,在系統將要發生記憶體溢位異常之前,將會把這類物件列進回收範圍進行第二次的回收。如果這次回收仍然沒有足夠的記憶體,就會丟擲記憶體溢位異常。在 jdk1.2 中提供了 SoftReference 類來實現軟引用
  • 弱引用也是用來描述非必須物件的,但是它的強度比軟引用更弱一些,被弱引用關聯的物件只能生存到下一次的垃圾回收之前。當垃圾收集器工作時,無論當前記憶體是否足夠,都會回收掉只被弱引用關聯的物件。在 jdk1.2 中提供了 WeakReference 類來實現弱引用
  • 虛引用也被稱為幽靈引用或幻影引用,它是最弱的一種引用關係。一個物件是否有虛引用的存在,完全不會對其生存時間造成影響,也無法通過虛引用來取得一個物件的例項。為一個物件設定虛引用關聯的唯一目的就是能在這個物件被收集時收到一個系統通知。在 jdk1.2 中提供了 PhantomReference 類來實現虛引用。
JVM 垃圾回收機制,何時觸發 MinorGC 等操作

Minor GC 也被稱為新生代 GC,指發生在新生代(PSYoungGen)的垃圾收集動作,新生代包括三塊記憶體區域 eden 區,fromFrom Survivor)區 與 toTo Survivor) 區。物件優先在 eden 建立並區分配記憶體,當 eden 區記憶體無法為一個新物件分配記憶體時,就會觸發 Minor GC。至於為什麼把新生代分為 3 個區,主要是為了新生代複製演算法的實現。

物件如何晉升到老年代

物件優先在新生代的 eden 區分配記憶體,但是也並不絕對,下面幾種情況物件會晉升到老年代

  • 大物件直接進入老年代。比如很長的字串,或者很大的陣列等
  • 長期存活的物件進入老年代。在堆中分配記憶體的物件,其記憶體佈局的物件頭中(Header)包含了 GC 分代年齡標記資訊。如果物件在 eden 區出生,那麼它的 GC 分代年齡會初始值為 1,每熬過一次 Minor GC 而不被回收,這個值就會增加 1 歲。當它的年齡到達一定的數值時(jdk1.7 預設是 15 歲),就會晉升到老年代中。
  • 動態物件年齡判定。當 Survivor 空間中相同年齡所有物件的大小總和大於 Survivor 空間的一半,年齡大於或等於該年齡的物件就可以直接進入老年代,而不需要達到預設的分代年齡。
EdenSurvivor的比例分配等

這個比例在每個 jdk 版本中可能是不一樣的,在 jdk1.7 中 EdenSurvivorfromto)的比例是 8 : 1。在 jdk1.8 是 6 : 1,如下
這裡寫圖片描述

什麼是類載入器的雙親委派模型

雙親委派模型是虛擬機器類載入機制 中有關類載入器的相關的東西。下面是類載入器的雙親委派模型
這裡寫圖片描述
類載入器的雙親委派模型並不是一個強制性的約束模型,而是 Java 設計者推薦給開發者的一種載入器方式。上面類載入器的父子關係一般不會以繼承的方式實現,而是採用組合的關係來複用父類載入器的程式碼。

工作過程:如果一個類載入器收到了類載入的請求,它首先不會自己去載入這個類,而是把這個請求委派給父類載入器去完成,每一個層次的類載入器都是如此,因此所有的載入請求都應該傳送到頂層的啟動類載入器,只有當父載入器無法完成這個載入請求時,子載入器才會嘗試自己去載入。

為什麼要有雙親委派模型呢?原因是雙親委派模型可以保證 Java 程式的穩定性。比如你有一個類,在不採用雙親委派模型的情況下,可能會有不同的載入器去載入這個類,不同類載入器加載出來的 Class 檔案必然不相同,這樣就造成了不一致性。

什麼是指令重排序、記憶體屏障與先行發生原則

想必這兩個名詞有很多 Java 程式設計師都或多或少的見過,因為理解起來比較困難,這裡就簡單的闡述一下,並不作詳細的分析

  • 指令重排序:CPU 採用了允許將多條指令不按程式規定的順序傳送給相應的電路單元處理。可以簡單的理解為不按程式的順序執行
  • 記憶體屏障:記憶體屏障是指指令重排序時,通過一個加鎖指令,把鎖前後指令的執行順序分隔開,不能把後面的指令重排序到記憶體屏障之前的位置
  • 先行發生原則:Java 記憶體模型中定義的兩項操作之間的偏序關係。如果 A 先行發生於 B 之前,操作 A 產生的影響會被操作 B 觀察到。這些影響可以是修改了記憶體中共享變數的值,傳送了訊息,呼叫了方法等

Java 中的 volatile 關鍵字有兩個主要的作用,一個是保證記憶體的可見性,還有一個作用就是禁止指令重排序的發生。

volatile 的語義,它修飾的變數一定執行緒安全嗎

上面我們已經簡答的提到了 volatile 關鍵字的作用,一個是保證記憶體的可見性,還有防止指令重排序。下面再來解釋一下記憶體可見性

  • 記憶體可見性:當一條執行緒修改了某個值,這個新值對於其他的執行緒是立即可見的,普通的變數不具備這個特徵

下面說結論,被 volatile 關鍵字修飾的變數不是執行緒安全的,因為 volatile 不能保證原子性。再另外的說一句,被 synchronized 修飾的程式碼塊具備原子性。

後面遇到相關的題目會陸續補充

相關推薦

阿里、美團、Oracle等大廠的Java虛擬機器試題集錦

“有程式碼的地方,就有江湖。”   程式設計師,就是“一人,一鍵,二機”行走其間的孤獨劍客。我們遊走程式碼江湖,彈指間,便可掀起一場風雨變革。而在江湖中狂蕩,必然要練就絕世武功,則需要內外兼備:精妙的招式,加之深厚的內功。武功的基礎是內功,一個內功低的人招式再奇妙,也打不過一個內功

Java 虛擬機器試題全面解析(乾貨)

周志明著的《深入理解 Java 虛擬機器》的乾貨~如有錯誤,歡迎指出 O(∩_∩)O 轉載請保留以上資訊。 JDK 是什麼? JDK 是用於支援 Java 程式開發的最小環境。 Java 程式設計語言 Java 虛擬機器 Java API類

Java 虛擬機器試題

如果物件的引用被置為null,垃圾收集器是否會立即釋放物件佔用的記憶體? 不會,在下一個垃圾回收週期中,這個物件將是可被回收的。 也就是說當一個物件的引用變為 null 時,並不會被垃圾收集器立刻回收,而是在下一次垃圾回收時才會釋放其佔用的記憶體。 f

Java虛擬機器試題精選(二)

概述現在面試Java開發時,基本都會問到Java虛擬機器的知識,根據職位不同問的內容深淺又有所區別。本文整理了10道面試中常問的Java虛擬機器面試題,希望對正在面試的同學有所幫助。11.介紹下垃圾收集

java 虛擬機器試題全面解答

周志明著的《深入理解 Java 虛擬機器》的乾貨~如有錯誤,歡迎指出 O(∩_∩)O 轉載請保留以上資訊。 JDK 是什麼? JDK 是用於支援 Java 程式開發的最小環境。 Java 程式設計語言 Java 虛擬機器 Java API類庫 JR

JVM(Java虛擬機器),多執行緒,集合,設計模式的一些試題

JVM(java Virtual Machine) Java虛擬機器,是一個虛擬的計算機,通過在真實的計算機上模擬模擬計算機功能來實現的, Java語言最重要的特點就是挎平臺。使用JVM就是為了支援與作業系統無關,實現挎平臺。 Java編譯器只要面向JVM,生成

從一道試題深入瞭解java虛擬機器記憶體結構

記得剛大學畢業時,為了應付面試,瘋狂的在網上刷JAVA的面試題,很多都靠死記硬背。其中有道面試題,給我的印象非常之深刻,有個大廠的面試官,順著這道題目,一直往下問,問到java虛擬機器的知識,最後把我給問住了。 我當時的表情是這樣的: 後來我有機會面試別人了,也按照他的思路出面試題,很多已經工作了2年的程式設

java中高級試題虛擬機,JVM調優,垃圾回收,多線程,內存模型

mybatis mys set 內存 集合 實現 runable ringbuf mon 面試問題: 一、Java基礎方面: 1、Java面相對象的思想的理解(主要是多態): http://blog.csdn.net/zhaojw_420/article/details/7

java虛擬機器常見面試題整理

-1.JVM的記憶體模型 1)程式計數器:當前執行緒所執行的位元組碼的行號執行器。再多執行緒上下文切換中將非常有用。 上下文切換:儲存到在載入的過程。可以理解為你看書看到第幾頁以後不看了,然後折了一下作為標誌,下次就從這裡開始看 2)java虛擬機器棧:我們常說的棧就是java虛擬

螞蟻金服初級Java電話面試 試題

ringbuf str eem 螞蟻 ren 電話 什麽 死鎖 hashmap 1.String, StringBuffer, StringBuilder 的區別,為什麽String 不可改變,StringBuilder可以改變? 2.HashMap 是不是有序的,有哪些有

Java線程試題 Top 50

pos 很難 設置 edt 維護 initial ips 有意 缺少 Java線程面試題 Top 50不管你是新程序員還是老手,你一定在面試中遇到過有關線程的問題。Java語言一個重要的特點就是內置了對並發的支持,讓Java大受企業和程序員的歡迎。大多數待遇豐厚的Java開

Java線程試題

linux下 rand 競態 java多線 答案 固定 枚舉類型 隨機 發現 不管你是新程序員還是老手,你一定在面試中遇到過有關線程的問題。Java語言一個重要的特點就是內置了對並發的支持,讓Java大受企業和程序員的歡迎。大多數待遇豐厚的Java開發職位都要求開發者精通多

大公司喜歡問的Java集合類試題

排序 ger stack cap out strong factor ack 繼承 大公司喜歡問的Java集合類面試題 看了一些所謂大公司的JAVA面試問題,發現對於JAVA集合類的使用都比較看重似的,而自己在這方面還真的是所真甚少,抽空也學習學習吧。 java.uti

Java常考試題(三)

請求 其中 默認 查找 重新 技術分享 block 知識 logs     序言        說說今天遇到的一件小事吧,在遇到問題,查找答案時,看到很多人的博客裏面都有提到關鍵字眼,可讓人覺得可恨的是,大多數人寫的博文中,基本上都是照著書上的語言發表的,看了跟沒看一樣,沒

Java常考試題(一)

div 並且 功能 不出 共享 情況 字符型 對象 java字節碼       序言         我是一只亂飛亂撞的菜鳥,寫的文章目前是以記錄自己學習,和方便以後查看,期待日後不久能通過自己的努力,獲得一點小小的成功,然後寫出我的學習經驗總結性文章來。         

入我新美大的Java後臺開發試題總結

情況 查詢優化 做什麽 工作 我認 人的 方便 xpl 別人   靜兒最近在總結一些面試題,那是因為做什麽事情都要認真。面試也一樣,靜兒作為新美大金融部門的面試官,負責任的告訴大家,下面的問題回答不上來,面試是過不了的。不過以下絕不是原題,你會發現自己實力不過硬,最終肯定是

2017年終巨獻阿裏、騰訊最新Java程序員試題,準備好進BAT了嗎

電商 als 下載 坐標 序列化 equals 比較 通過 研究 Java基礎 進程和線程的區別; Java的並發、多線程、線程模型; 什麽是線程池,如何使用? 數據一致性如何保證;Synchronized關鍵字,類鎖,方法鎖,重入鎖; Java中實現多態的機制是什麽; 如

Java高級試題

結果 tcp三次握手 深度優先 必須 模式 session shm 通訊 obj 一.基礎知識: 1)集合類:List和Set比較,各自的子類比較(ArrayList,Vector,LinkedList;HashSet,TreeSet); 2)HashMap的底層實現,之後

[ 轉載 ] Java線程試題 Top 50 (轉載)

top cnblogs pan style java log java線程 轉載 -s http://www.cnblogs.com/dolphin0520/p/3958019.html[ 轉載 ] Java線程面試題 Top 50 (轉載)

Java後臺開發試題總結

情況 swap sql 行數 his 本地方法棧 特性 jndi buffer 1>如何定位線上服務OOM問題  2>JVM的GC ROOTS存在於那些地方 3>mysql innodb怎樣做查詢優化 4>java cas的概念 Java服務OO