JVM學習筆記(2)——類型生命周期
直奔主題吧
- 一個java類經過裝載、連接和初始化三步達到程序可用狀態,其中連接又包含驗證、準備和可選的解析過程,驗證是檢查數據格式、準備是分配內存、解析負責把常量池的符號引用轉換為直接引用。
- jvm必須在每個類或接口首次主動使用時初始化,有六種主動使用場景:1)創建某個類的新實例,2)調用某個類的靜態方法,3)使用某個類或接口的靜態字段,用final修飾的靜態字段除外,它被初始化為一個編譯時的常量表達式,4)調用Java api中的某些反射方法,5)初始化某個類的子類,6)虛擬機啟動時某個被標明為啟動類的類(含有main方法的類)。
- 某個類要初始化,其所有的祖先類必須之前被初始化;接口則不同,只有在某個接口聲明的非常量字段被使用時,該接口才初始化。
- 類裝載的三個基本動作:通過完全限定名找到二進制數據流,解析為方法區內的數據結構,創建一個該類型的java.lang.Class的實例。
- 類裝載有可能存在預先裝載,在預先裝載時出問題,會拋出一個LinkageError的異常。
- 在準備階段,內存分配是初始化為默認值的,而不是實際的初始值。默認值列表如下:
類型 默認初始值 int 0 long 0L short (short)0 char '\u0000' byte (byte)0 boolean false reference null float 0.0f double 0.0d - 在準備和解析完后,才進入初始化階段,為變量賦予真正的初始值。
- 初始化類的步驟:1)如果類存在直接超類,且直接超類還沒有被初始化,就先初始化直接超類。2)如果類存在一個類初始化方法,就執行此方法。
- 第一個被初始化的類永遠都是Object。
- 所有的類變量初始化語句和類型的靜態初始化器都被java編譯器收集在一起,放到一個特殊的方法中——<clinit>。
- 如果接口包含任何不能在編譯時被解析成為一個常量的字段初始化語句,接口就會擁有一個<clinit>方法。
- 類變量如果直接賦常量值,那么類是不會初始化的。
- 類實例化的四種途徑:1)new操作符。2)調用Class或Constructor的newInstance()方法。3)調用任何現有對象的clone()方法。4)通過ObjectInputStream的readObject()方法反序列化。
- JVM為它編譯的每一個類都至少生成一個實例初始化方法<init>。
- 使用啟動類裝載器裝載的類,永遠都不會被垃圾收集。
posted on 2012-09-19 18:13 changedi 閱讀(391) 評論(0) 編輯 收藏 所屬分類: Java技術