JVM學習

Java體系結構:
   a.java程序設計語言   b.各類硬件平臺上的java虛擬機  c.Class文件   d.JavaApi 類庫  e.第三方類庫
JDK:  java程序設計語言、Java虛擬機、JavaAPI
    堆內存和棧內存:棧內存其實是指虛擬機棧(或者說是虛擬機棧中的局部變量表 )
  jvm內存:方法區(線程共享區域)、虛擬機棧、本地方法棧、堆(線程共享區域)、程序計數器、運行時常量池(存放編譯時生成的各類字面量和符號引用)
         方法區存放各個線程共享的內存區域,主要用於存儲已被jvm加載的類信息、常量、靜態常量等。
         String.intern()會因32和64的jvm而出現不一樣的現象。 
           垃圾回收機制(分代回收 ):新生代和老年代主要指Eden空間、From Survivor空間、To Survivor空間等
   b.每個被裝載的時候,Java虛擬機都會監視這個類,看是被啓動類裝載器仍是用戶定義的裝載器裝載。當被裝載的類引用了另外一個類,虛擬機就會使用裝載
  第一個類的類裝載器狀態被引用的類
   c.若是想解決相對獨立的Java程序的性能問題而又不須要動態擴展,預編譯多是個好辦法。
 2.NIO(new InputStream/OutputStream)基於通道(channel)和緩衝區(buffer)的I/O方式

3.對象在內存中存儲的佈局:對象頭、實例數據和對齊填充 
   jvm內存管理和線程調度的說明不清楚,使得程序員沒法瞭解應該如何調度線程,沒法控制線程,所以難成爲某些特定系統方案(如須要實時響應的軟件)
   
 
4.hotspotVM的自動內存管理系統要求對象的起始地址必須是8字節的整數倍,即對象的大小是8字節的整數倍
5.reference類型在jvm中只規定一個指向對象的引用,沒有規定如何訪問對應的位置和方法,即由jvm實現而定。
   主流訪問方式:句柄和指針兩種。
   句柄:優勢在引用處存儲的是穩定的句柄地址,在對象被移動時(垃圾回收時移動對象是很是普通的行爲)只改變句柄中的實例指針,不改變引用地址
   指針:速度更快,節省一次指針定位的時間開銷



5.內存溢出:
   stackoverflow:線程請求的棧深度大於虛擬機所容許的最大深度       不斷new對象
   outofmemoryerror:虛擬機在擴展棧沒法申請到足夠的空間。           不斷啓動新的線程就會出現

6.方法區和運行時常量溢出:
  String.intern()  //若字符串常量池裏已經包含該字符串,則 返回相應的字符串String對象;不然將此String對象加入常量池。
  list.add(String.valueOf(i).intern());   //會形成內存溢出

7.爲何jvm管理內存不使用引用計數算法來控制內存回收?
   由於很難解決對象之間相互循環引用的問題

8.可行性分析回收:以GCRoot做爲起點,開始向下搜索(引用鏈),當一個對象到GCroot沒有任何引用鏈相連,及證實對象不可用。


ClassLoader分爲ExtClassLoader:用於加載Java擴展的API(/lib/ext中的類)    和 AppClassLoader用於加載ClassPath設置目錄中的Class.
   特色:
           a.ClassLoader具備層次關係,loadClass()是入口。             b.Class.forName()能動態加載一個類
          c.不一樣的類加載器分別建立的同一個類的字節碼數據屬於不一樣的對象,沒有關聯。
 2.JVM:進程級別的實例
       a.產生:當啓動一個JAVA程序時,一個JVM實例就會產生,任何一個public static void main(String args[])的class均可以做爲JVM運行的起點。
       b.運行:main()做爲該程序初始線程的起點,該應用中的其餘線程都由該線程啓動。
               1.非守護線程:如main() 
               2.守護線程:由jvm本身使用,程序能夠指定線程爲守護線程
       c.消亡:程序中全部守護線程都終止時,jvm才能退出,也能夠經過Runtime類或者System.exit()來退出(安全管理器容許才行)
3.JVM體系結構
       a.類加載器(classLoader) 裝載 .class文件
       b.執行引擎(執行字節碼或者本地方法)
       c.運行時數據區(方法區、堆、java棧、PC寄存器、本地方法棧)

4.JVM類加載器:html

       a.經過類名+包名+ClassLoader實例ID找到對應的二進制字節碼並加載JVM中java

       b.連接:1.負責對二進制字節碼的格式進行校驗、初始化裝載類中的靜態變量以及解析類中調用接口、類。程序員

                     2.完成校驗以後,初始化類中的靜態變量並賦初值。算法

                     3.最後對類中的屬性、方法等進行驗證,以確保其須要的屬性、方法和對應的權限存在,可能緩存

                        報NoSuchMethodErrorNoSuchFieldError等錯誤信息。安全

5.初始化:jvm

      a.執行類中的靜態初始化代碼、構造器代碼以及靜態屬性的初始化。佈局

          四種狀況下會執行:性能

                  a.調用了new                   b.反射調用了類中的方法優化

                  c.子類調用了初始化       d.JVM啓動過程當中的初始化類

 6.JVM類加載順序:

      a.兩種類加載器:啓動類裝載器(JVM實現的一部分)和用戶自定義類加載器(Java程序的一部分,必須是ClassLoader類的子類)

 7.JVM裝載順序:

      a.JVM啓動時,由BootStrap向User-Defined方向加載類;

          應用進行ClassLoader時,由User-Defined向BootStrap方向查找並加載類。

      1.Bootstrap ClassLoader(JVM的根ClassLoader),JVM啓動時初始化此ClassLoader,並由此ClassLoader完成jre/lib/rt.jar(sun JDK實現)

         中全部class文件的加載。   注:rt.jar包含java規範定義的全部接口以及實現

      2.Extension ClassLoader   JVM用於加載擴展功能的一些jar包

      3.System ClassLoader   JVM用來加載啓動參數指定的Classpath中的jar包以及目錄,如AppClassLoader

      4.User-Defined ClassLoader  

               繼承ClassLoader自定義ClassLoader類,用於加載非Classpath中的jar包以及目錄

8.JVM經常使用幾個方法:

       a.loadClass:  加載指定名字的類,先從已加載的類中尋找,沒有則繼續從parent ClassLoader中尋找,仍沒找到則從System ClassLoader中尋找,

          最後調用findClass方法查找;   如要改變類的加載順序,可覆蓋此方法實現。

       b.findLoadedClass:  從ClassLoader實例對象的緩存中尋找已加載的類,調用native方法。

       c.findClass:   直接拋出ClassNotFoundException,能夠經過覆蓋此方法和loadClass來加載相應的類。

       d.findSystemClass  從System ClassLoader中尋找類,未找到,則繼續從BootStrap ClassLoader尋找,沒有就返回null.

       e.defineClass  將二進制的字節碼轉換爲Class對象

       f.resolveClass  負責完成Class對象的連接,如已連接過,則直接返回。

9.JVM執行引擎

       a.invokestatic:調用類的static方法

       b.invokevirtual:調用對象實例的方法

       c.invokeinterface:將屬性定義爲接口來調用

       d.invokespecial: 當JVM對於初始化對象(Java構造器的方法爲:<init>)以及調用對象實例中的私有方法時調用

   JVM主要的執行技術有:

        1.解釋    第一代JVM

        2.即時編譯  第二代JVM

        3.自適應優化 如目前的HotspotJVM  開始對全部的代碼都採起解釋執行的方式,並監視代碼的執行狀況,

                對那些常常調用的方法啓動一個後臺線程,將其編譯優化爲本地代碼;如該方法再也不頻繁使用,則

                取消編譯過的代碼,仍對其解釋執行。

        4.芯片級直接執行

10.JVM運行時數據區:

        1.PC寄存區:存儲每一個線程下一步將執行的指令,如該方法被native修飾,則PC寄存器不存儲任何信息。

        2.JVM棧 :  JVM棧是線程私有的,每一個線程建立的同時都會建立JVM棧,JVM棧存放的爲當前線程的基本類型

            變量(八種數據類型:booleancharbyteshortintlongfloatdouble)、部分返回的結果以及

            Stack Frame; 非基本類型的對象在JVM棧上僅存放一個指向堆的地址。

           http://www.open-open.com/lib/view/open1408453806147.html

11.多核並行:

       1.java.util.concurrent.forkjoin包









相關文章
相關標籤/搜索