1、 Java總體(java編程語言、java API、java文件格式和虛擬機) 1
2、 java虛擬機結束生命周期 1
3、 類的加載、連接和初始化 2
4、 java對類的使用方式分為兩種: 2
4、 類的加載 2
5、 加載.class文件的方式 2
6、 兩種類加載器 3
7、 類的連接階段:就是將已經讀入內存的二進制數據合并到虛擬機的運行時環境中去 3
8、 類的驗證的內容: 3
9、 類的準備和解析: 3
10、 類的初始化: 3
11、 類的初始化時機:類被主動調用時*(六種 上面) 3
12、 類加載器: 3
13、 類的驗證: 3
14、 類的準備和解析 3
15、 類的初始化步驟: 3
16、 類的初始化的時機 4
17、 類的加載父類委托機制(更好的保證java平臺安全??): 4
18、類加載器: 4
19、 類的命名空間: 4
20、 JVM內存管理機制 4
21、 java堆和棧的區別:內存劃分為堆內存和棧內存 5
22、 java內存泄露和內存溢出 5
23、 JVM工作原理 5
1、Java總體(java編程語言、java API、java文件格式和虛擬機)

2、java虛擬機結束生命周期
A、執行System.exit()方法
B、程序正常執行結束
C、程序執行過程中遇到異常或錯誤而異常終止
D、由于操作系統出現錯誤而導致java虛擬機進程終止
3、類的加載、連接和初始化
A、加載:查找并加載類的進制數據
B、連接:
驗證:確保被加載類的正確性
準備:為類的靜態變量分配內存,并將其初始化為默認值
解析:把類中的符號引用轉換為直接引用
C、初始化:為類的靜態變量賦予正確的初始值

4、java對類的使用方式分為兩種:
所有java虛擬機實現必須在每個類或接口被java程序“首次主動使用”時才初始化他們
A、主動使用(會導致類的初始化)
Ø 創建類的實例
Ø 訪問某個類或接口的靜態變量,或者對該靜態變量賦值
Ø 調用類的靜態方法
Ø 反射(如Class.forName("com.ss.Test"))
Ø 初始化一個類的子類
Ø Java虛擬機啟動時被標明為啟動的類
除以上六種情況,其它使用java類的方式都被看作是對類的被動使用,不會導致類的初始化
B、被動使用
4、類的加載
是指將類的.class文件中的二進制數據讀入到內存中,將其放在運行時數據區的方法區內,然后在堆區創建一個java.lang.Class對象,用來封裝方法和區內的數據結構
5、加載.class文件的方式
A、從本地系統中直接加載
B、通過網絡下載.class文件
C、從ZIP,JAR等歸檔文件中加載.class文件
D、從專有數據庫中提取.class文件
E、將java源文件動態編譯為.class文件

6、兩種類加載器
A、java虛擬機自帶的加載器
Ø 根類加載器(Bootstrap)
Ø 擴展類加載器(Extension)
Ø 系統類加載器(System)
B、用戶自定義的類加載器
Ø java.lang.ClassLoader的子類
Ø 用戶可以定制類的加載方式
7、類的連接階段:就是將已經讀入內存的二進制數據合并到虛擬機的運行時環境中去
8、類的驗證的內容:
A、類文件的結構檢查:確保類文件遵從Java類文件的固定格式
B、語義檢查:確保類本身符合JAVA語言的語法規定,比如驗證final類型的類沒有子類,以及final類型的方法有沒有被覆蓋
C、字節碼的驗證:確保字節碼流(由操作碼的單字節指令組成)可以被虛擬機安全的執行。
D、二進制兼容性的驗證:確保相互引用的類之間協調一致。
9、類的準備和解析:
A、準備:JAVA虛擬機為類的靜態變量分配內存,并設置默認値。
B、解析:JAVA虛擬機會把類的二進制數據中的符號引用替換為直接引用。
10、類的初始化:
A、靜態變量初始化:靜態變量的聲明式初始化和靜態變量在初始化塊中初始化。
B、初始化步驟:
Ø 假如類沒有被加載和連接,那先進行加載和連接
Ø 假如類存在直接的父類,并且這個父類沒有被初始化,那先初始化直接的父類
Ø 假如類中存在初始化,那依次執行初始化語句
11、類的初始化時機:類被主動調用時*(六種 上面)
Ø 只有當程序訪問的靜態變量或靜態方法確實在當前類或當前接口定義時,才可以認為是對類或接口的主動使用
Ø 調用ClassLoader類的loadClass方法加載一個類,并不是對類的主動使用,不會導致類的初始化
12、類加載器:
A、JAVA虛擬機自帶的加載器:根類加載器(Bootstrap)、擴展類加載器(Extension)、系統類加載器(System)
B、用戶自定義的類加載器:java.lang.ClassLoader的子類、用戶可以定制類的加載方式
類的加載時機:JVM規范允許類加載器在預料某個類將要被使用時就預先加載它,如果在預先加載時遇到.class文件缺失或存在錯誤,類加載器必須在程序首次主動使用該類時才報告錯誤(LinkageError)。如果這個類一直沒有被程序主動使用,那么類加載器就不會報告錯誤。
13、類的驗證:
類被加載后就進入了連接階段,連接就是將已經讀入內存的類的二進制數據合并到虛擬機的運行環境中去。
A、驗證的內容:
Ø 類文件的結構檢查:確保類文件遵從JAVA類文件的固定格式
Ø 語義檢查:確保類本身符合JAVA語言的語法規定。比如驗證final類型的類沒有子類,以及final類型的方法沒有被覆蓋。
Ø 字節碼驗證:確保字節碼流可以被java虛擬機安全的執行。(字節碼:代表Java方法,它是由操作碼的單字節指令組成的序列,每一個操作碼后都跟有一個或多個操作數,即驗證是否有合法的操作數)
Ø 二進制兼容性的驗證:確保相互引用的類之間協調一致。(例如在Work類中調用了Car類的run方法,在驗證Worker類時就會驗證Car類中是否有run方法,如果沒有則報NoSuchMethodError錯誤)
14、類的準備和解析
A、類的準備:java虛擬機為類的靜態變量分配內存,并設置默認的初始值。
B、類的解析:Java虛擬機會把類的二進制數據中的符號引用替換為直接引用。
(在Worker類的二進制數據中,包含了一個對Car類的run方法的符號引用,在解析階段,java虛擬機會把這個符號引用替換為一個指針,指向Car類的run方法在方法區內的內存位置,這個指針就是直接引用)
15、類的初始化步驟:
A、假如這個類沒有被加載和連接,就先進行加載和連接
B、假如類存在直接的父類,并且這個父類沒有被初始化,那先初始化直接父類
C、假如類中存在初始化語句,那就依次的執行這些初始化語句。
16、類的初始化的時機
A、調用ClassLoader類的loadClass方法加載一個類,并不是對類的主動使用,不會導致類的初始化。
B、只有當程序訪問的靜態變量或靜態方法確實在當前類或當前接口中定義時,才可以認為是對類或接口的主動使用
17、類的加載父類委托機制(更好的保證java平臺安全??):
在父類委托機制中,除了java虛擬機自帶的根類加載器,其余的類加載器有且只有一個父類加載器。(當Java程序請求加載器Load1加載Sample類時,Load1會首先委托其父類加載器進行加載,如果父類加載器不能對Sample進行加載,則由Load1進行加載。)
A、優點:提高了軟件系統的安全性。在此機制下,用戶自定義的類加載器不可能加載應由其父類加載器加載的可靠類,從而防止了不可靠甚至惡意的代碼代替父類加載器加載可靠代碼。(例如其他由任意用戶自定義的類加載器不可能加載含有惡意代碼的java.lang.Object類)
18、類加載器:
A、根類加載器(Bootstrap):該類加載器沒有父類加載器,它負責加載虛擬機的核心類庫,如Java.lang.*等。(java.lang.Object就是由根類加載器進行加載的。根類加載器從系統屬性sun.boot.class.path中指定的目錄中加載類庫。根類加載器的實現依賴于底層操作系統,屬于虛擬機的一部分,它并沒有繼承java.lang.ClassLoader類)
B、擴展類加載器(Extension):它的父類加載器為根類加載器,它從java.ext.dirs系統屬性指定的目錄或jre\lib\ext中加載類庫。(如果把用戶創建的JAR放在這個目錄下,也會由擴展類加載器進行加載,擴展類加載器是純JAVA類,它是java.lang.ClassLoader的子類)
C、系統類加載器(System):也稱為應用類加載器,它的父類加載器為擴展類加載器。它從環境變量classpath或者系統屬性java.class.path所指定的目錄中加載類,它是用戶自定義的類加載器的默認的父類加載器。系統類加載器是純java類,是java.lang.ClassLoader的子類。

19、類的命名空間:
每個加載器都有自己的命名空間。這個命名空間由該類加載器及所有的父類加載器所加載的類組成。在同一命名空間中,不會出現類的完整名字相同的兩個類;在不同的命名空間有可能出現。
20、JVM內存管理機制
內存空間劃分為:堆、JVM方法棧、方法區、本地方法棧、PC寄存器
A、堆:堆用于存儲對象實例及數組值。Java中所有通過new創建的對象的內存都在這里分配,heap中對象所占的內存由GC進行回收。(32位OS最大為2GB,64位沒有限制,-Xms -Xmx)
B、JVM方法棧:為線程私有,其在內存分配上非常高效,當方法運行完畢時,其對應的棧幀占用的內存也會被自動釋放。(JVM方法棧空間不足時,會拋出StackOverflowError,可通過-Xss指定大小)
C、方法區:要加載的類的信息(名稱、修飾符等)、類中的靜態變量、類中定義為final類型的變量、類中的field信息、類中的方法信息。(最小16M,最大為64M,通過-XX:PerSize -XX:MaxPermSize)
D、本地方法棧:用于支持native方法的執行,存儲每個native方法調用的狀態。在SUN JDK的實現中和JVM方法棧是同一個。
E、PC寄存器:占用的可能為CPU寄存器或操作系統內存
21、java堆和棧的區別:內存劃分為堆內存和棧內存
A、在函數中定義和一些基本類型的變量和對象的引用變量都在函數的棧內存中進行分配。(當定義變量時,JAVA就在棧內存中為其分配內存空間,當超過變量的作用域后,java會自動釋放該變量占用的內存)
B、堆內存用來存放由new創建的對象和數組。在堆中分配的內存,Java虛擬機自動的進行垃圾回收管理。(在棧中定義一個特殊變量,讓這個變量的取值等于數組或對象在堆內存中的首地址,在棧中的這個變量就變成了數組或對象的引用變量)
C、
22、java內存泄露和內存溢出
A、內存泄露:分配出去的內存回收不了
B、內存溢出:指系統的內存不夠用
23、JVM工作原理
A、創建JVM裝載環境和配置:JVM提供的方式是操作系統的動態連接文件。(首先查找JRE路徑,java通過getApplicationHome獲得java.exe的絕對路徑,然后判斷/jre、\bin下面哪個存在java.dll,如果存在就把其中一個做為JRE的路徑。)
B、裝載JVM.dll:通過前面得到了JVM的路徑,java通過LoadJavaVM來裝入JVM.dll文件,裝入方式是通過WindowAPI函數來實現的。(LoadLibrary裝載JVM.dll動態庫,然后把JVM.dll函數中導出的JNI_CreateJavaVM和JNI_GetDefaultJavaVMInitArgs掛接到InvocationFunction的這兩個函數指針變量上,jvm.dll裝載工作宣告完成)
C、初始化JVM.dll并掛界到JNIENV實例( 初始化JVM,獲得本地接口,這樣就可以在java中調用JVM函數了。調用Invacation-->CreateJavaVM也就是JVM的JNI_CreateJavaVM來獲得JNIEnv的實例)
D、調用JNIEnv實例裝載并處理class類。
(運行java程序:一種是JAR包,一種是.class文件。前者java -jar xxx.jar運行的時候,java.exe調用GetMainClassName函數,該函數獲得JNIEnv實例然后調用java類java.util.jar.JarFileJNIEnv中的方法getMainfest()并返回Mainfest對象中取得getAttributes("Main-Class")的值即jar包中的META-INF/MANIFEST.MF指定的主類名運行主類,之后main函數會調用java.c中的loadClass方法裝載該類。然后main函數調用JNIEnv實例getStaticMethodID方法查找主類中的main(String[] args),并判斷該方法是否為public方法,然后調用JNIEnv實例的CallStaticvoidMethod調用java類的main方法)
參考文檔:
深入理解JVM :http://www.iteye.com/topic/752755
深入剖析JVM原理及特點:http://blog.csdn.net/harry0514/article/details/5939459