淺談JVM(上)

一:JVM的位置所在java

 

 JVM的位置是在操做系統和java程序之間,因此JVM並非直接操做底層硬件系統的。因此插入一個話題,若是在新買的電腦上有java的環境,那應該已是被用過的,除非商家安裝的java環境,可是這種概率應該不高,因此說大機率應該是被坑了,別人用過的電腦(能夠在cmd中,使用命令java -verison來查看)。c++

二:JVM的內存結構安全

 

 

 

(1)首先將.java源程序編譯成.class文件(二進制)網絡

   (2)   而後將.class文件加載到類加載器中,這個class文件多是本地的.class文件,也多是從網絡上獲取過來的.class文件(實現序列化接口)數據結構

   (3)   類加載器對class文件進行加載=>鏈接=>初始化的操做jvm

   (4)   下面則是到了JVM的運行數據區中(堆,棧,方法區,本地方發棧以及程序計數器)spa

類加載器(ClassLoader):附一張圖操作系統

 

 

1:加載:是將本地的.class文件(或者網絡節點的.class文件)中的二進制讀入到內存中,把它放到運行時數據區的方法中,而後再堆區建立一個Class對象,用於封裝類在方法區中的數據結構。class封裝了類在方法區中的結構,而且向java程序提供了類在方法區中的數據結構接口。類的加載是由加載器完成的,加載器有:啓動類加載器、擴展類加載器、系統類加載器、用戶自定義類加載器。這裏就牽扯到了java的雙親委派機制。線程

雙親委派機制:當某個類加載器須要加載某個.class文件,他首先把這個任務委託給他的上級類加載器,遞歸這個操做,若是上級的類加載器沒有加載,本身才會去加載這個類。code

類加載器的類別:

(1)BootstrapLoader(啓動加載器)c++編寫,加載java核心庫 java.*,構造ExtClassLoaderAppClassLoader。因爲引導類加載器涉及到虛擬機本地實現細節,開發者沒法直接獲取到啓動類加載器的引用,因此不容許直接經過引用進行操做。

(2)ExtClassLoader (標準擴展類加載器)java編寫,加載擴展庫,如classpath中的jre ,javax.*或者java.ext.dir 指定位置中的類,開發者能夠直接使用標準擴展類加載器。

(3)AppClassLoader(系統類加載器)java編寫,加載程序所在的目錄,如user.dir所在的位置的class

(4)CustomClassLoader(用戶自定義類加載器)java編寫,用戶自定義的類加載器,可加載指定路徑的class文件

 

  做用: 1:防止重複加載同一個.class,經過委託到上面問一問,加載過了,就不用在加載一遍。保證數據安全。

              2:保證核心.class不被篡改,經過委託方式,不會去篡改核心.class,即便篡改也不會去加載,即便加載也不會是同一個.class對象了。不一樣的加載器加載同一個.class也不是同一個Class對象。這樣保證了Class執行安全。

 

2:鏈接:

  • 驗證:保證被加載的類的正確性;

  • 準備:給類靜態變量分配內存空間,賦值一個默認的初始值;

  • 解析:把類中的符號引用轉換爲直接引用

3:初始化:給類的靜態變量賦值正確的值。

 

運行時數據區:

(1)方法區:Method Area 方法區 是 Java虛擬機規範中定義的運行是數據區域之一,和堆(heap)同樣能夠在線程之間共享!

 JDK1.7以前:永久代是用於存儲一些虛擬機加載類信息,常量,字符串,靜態變量等等,永久代是有限制的,若是滿了會報OutofMemoryError:PerGen

 JDK1.8以後:完全將永久代移除HotPot Jvm,java Heap 中或者MetaSpace(Native Heap)空間

                       元空間就是方法區在 HotSpot jvm 的實現;

                       方法區重要就是來存:類信息,常量,字符串、靜態變量、符號引用、方法代碼。。。。。。

                      元空間和永久代,都是對JVM規範中方法區的實現。

                      元空間和永久代最大的區別:==元空間並不在Java虛擬機中,使用的是本地內存!==

        -XX:MetasapceSize10m

(未完待續......很抱歉寫做經驗不太多,可能寫的有些很差,後面會提升本身的表達能力!!!)

相關文章
相關標籤/搜索