一: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.*
,構造ExtClassLoader
和AppClassLoader
。因爲引導類加載器涉及到虛擬機本地實現細節,開發者沒法直接獲取到啓動類加載器的引用,因此不容許直接經過引用進行操做。
(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)空間
方法區重要就是來存:類信息,常量,字符串、靜態變量、符號引用、方法代碼。。。。。。
元空間和永久代,都是對JVM規範中方法區的實現。
元空間和永久代最大的區別:==元空間並不在Java虛擬機中,使用的是本地內存!==
-XX:MetasapceSize10m
(未完待續......很抱歉寫做經驗不太多,可能寫的有些很差,後面會提升本身的表達能力!!!)