Java面試總結——平臺與內存原理

1.JVM加載class文件的原理機制是什麼
當運行指定程序時,JVM會將編譯生成的.class文件按照需求和一定的規則加載到內存中,並組織成爲一個完整的Java應用程序,這個加載過程是由**類加載器(ClassLoader)**來完成的。

隱式加載 顯式加載
使用new等方式創建對象時,隱式調用類加載到JVM 直接調用class.forName()方法把所需的類加載到JVM中

Java類的加載是動態的,它並不會一次性將所有類全部加載後再運行,而是保證程序運行的基礎類(像是基類)完全加載到jvm中,至於其他類,則在需要的時候才加載。這當然就是爲了節省內存開銷。
Java的類加載器有三個,對應Java的三種類:

 Bootstrap Loader  // 負責加載系統類 (指的是內置類,像是String,對應於C#中的System類和C/C++標準庫中的類)
        | 
      - - ExtClassLoader   // 負責加載擴展類(就是繼承類和實現類)
                      | 
                  - - AppClassLoader   // 負責加載應用類(程序員自定義的類)

三個加載器各自完成自己的工作,但它們是如何協調工作呢?哪一個類該由哪個類加載器完成呢?爲了解決這個問題,Java採用了委託模型機制
委託模型機制的工作原理很簡單:當類加載器需要加載類的時候,先請示其Parent(即上一層加載器)在其搜索路徑載入,如果找不到,纔在自己的搜索路徑搜索該類。這樣的順序其實就是加載器層次上自頂而下的搜索,因爲加載器必須保證基礎類的加載。
我們可以通過這樣的代碼來獲取類加載器:

ClassLoader loader = ClassName.class.getClassLoader();
ClassLoader ParentLoader = loader.getParent();

前面是對類加載器的簡單介紹,它的原理機制非常簡單,就是下面幾個步驟:

1.裝載:查找和導入class文件;

2.連接:

  (1)檢查:檢查載入的class文件數據的正確性;

  (2)準備:爲類的靜態變量分配存儲空間;

  (3)解析:將符號引用轉換成直接引用(這一步是可選的)

3.初始化:初始化靜態變量,靜態代碼塊。

  這樣的過程在程序調用類的靜態成員的時候開始執行,所以靜態方法main()纔會成爲一般程序的入口方法。類的構造器也會引發該動作。
2.什麼是GC(Garbage Collection)

垃圾回收主要作用是回收程序中不再使用的內存。c/c++需要開發人員仔細地管理好內存分配與釋放,java語言則提供了垃圾回收器來自動檢測對象的作用域,可以自動地把不再使用的存儲空間釋放掉。垃圾回收器主要負責完成以下3項任務:分配內存、確保被引用對象的內存不被錯誤地回收以及回收不再引用的對象的內存空間。
判斷一個對象是否應該被回收(哪些內存需要回收)
(1)引用計數法
(2)對象可達性分析。由於引用計數法存在互相引用導致無法進行GC的問題,所以目前JVM虛擬機多使用對象可達性分析算法。該方法的基本思想是通過一系列的“GC Roots”對象作爲起點進行搜索,如果在“GC Roots”和一個對象之間沒有可達路徑,則稱該對象是不可達的,不過要注意的是被判定爲不可達的對象不一定就會成爲可回收對象。被判定爲不可達的對象要成爲可回收對象必須至少經歷兩次標記過程,如果在這兩次標記過程中仍然沒有逃脫成爲可回收對象的可能性,則基本上就真的成爲可回收對象了。
判斷什麼時候回收
即使是被判斷不可達的對象,也要再進行篩選,當對象沒有覆蓋finalize()方法,或者finalize方法已經被虛擬機調用過,則沒有必要執行;
如果有必要執行——放置在F-Queue的隊列中——Finalizer線程執行。
如何進行回收
常用的垃圾回收算法:
(1)標記 -清除
不足:效率問題;空間問題(會產生大量不連續的內存碎片)
(2)標記-整理
把堆中活動的對象移動到一端,這樣就會在堆中另外一端留出很大的一塊空閒區域。簡化消除碎片的工作、但是帶來了性能的損失。
(3)標記-複製
將可用內存按容量分爲大小相等的兩塊,每次都只使用其中一塊;
可以消除內存碎片,對內存調整降低了程序執行的效率。
(4)分代回收
把堆分成兩個或者多個子堆,每個子堆視爲一代,優先收集年幼代,如果一個對象經過多次收集仍然存活,那麼可以把這個對象轉移到高一級的堆裏,減少對其的掃描次數。

3.java中堆和棧有什麼區別
比較
主要區別 存放基本數據類型與引用變量 存放運行時創建的對象(new)
功能及作用 用來執行程序 用來存放對象
存取速度 快 (大小和生存期確定,缺乏靈活性) 相對慢(動態分配內存、生存期不告訴編譯器)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章