1、JVM的位置:JVM是在操作系統上面的應用軟體 JVM虛擬機有三種如下: ① Sun公司的HotSpot; ② BEA公司的JRockit; ③ IBM公司的J9 JVM; java虛擬機屬於第一種: 2、JVM的體繫結構: 3、類載入器 作用:載入class文件 (類是模板,對象是具體的) 簡 ...
1、JVM的位置:JVM是在操作系統上面的應用軟體
JVM虛擬機有三種如下:
① Sun公司的HotSpot;
② BEA公司的JRockit;
③ IBM公司的J9 JVM;
java虛擬機屬於第一種:
2、JVM的體繫結構:
3、類載入器
作用:載入class文件 -------(類是模板,對象是具體的)
簡單執行過程:
雙親委派機制:
定義:在程式運行時某個類載入器需要載入某個.class
文件時,它首先把這個任務委托給他的上級類載入器(即ExtClassLoader),ExtClassLoader載入器在把任務委托給他的上級類BootstrapClassLoader,如果BootstrapClassLoader沒有載入就到ExtClassLoader載入,如果ExtClassLoader沒有載入就自己載入,按照這個遞歸這個操作,來完成載入該文件的機制就稱為雙親委派機制
類載入器的類別:
(1)BootstrapClassLoader(啟動類載入器)
它是由C++寫的,載入java核心庫-->java.*;java/lib目錄下的jar,自己複製進去也會載入,但是java環境會被不壞
(2)ExtClassLoader(標準擴展類載入器)
它是由java寫的,載入擴展庫即java/lib/ext目錄下的jar,java.ext.dir
指定位置中的類,開發者可以直接使用標準擴展類載入器。
(3)AppClassLoader(系統類載入器)
它是由java寫的,載入程式所在的目錄,我們自己寫的類大多數使用這個如user.dir
所在的位置的class
(4)CustomClassLoader(用戶自定義類載入器)
它是由java寫的,用戶自定義的類載入器,可載入指定路徑的class
文件,Tomcat實現就是有自己的載入器
雙親委派機制的作用:
1)、防止載入相同的class文件,保證數據的安全
2)、防止核心類被破壞,造成java環境的污染
4、沙箱安全機制
防止遠程代碼(病毒)入侵
5、native
凡是帶native關鍵字的,說明java的作用範圍達不到了,只能調用C語言的庫;會進入本地方法棧;然後會調用本地介面(JNI),JNI作用:擴展java的使用,融合不同的語言為java所用;最初的C、C++,它在記憶體區域中專門打開調了一塊標誌區域:本地方法棧,登記native方法
例子:源碼:Thread的類中的----》private native void start0();
6、PC寄存器
1)、PC寄存器( PC register ):每個線程啟動的時候,都會創建一個PC(Program Counter,程式計數器)寄存器。PC寄存器里保存有當前正在執行的JVM指令的地址。 每一個線程都有它自己的PC寄存器,也是該線程啟動時創建的。保存下一條將要執行的指令地址的寄存器是 :PC寄存器。PC寄存器的內容總是指向下一條將被執行指令的地址,這裡的地址可以是一個本地指針,也可以是在方法區中相對應於該方法起始指令的偏移量。
2)、每個線程都有一個程式計數器,是線程私有的,就是一個指針,指向方法區中的方法位元組碼(用來存儲指向下一條指令的地址,也即將要執行的指令代碼),由執行引擎讀取下一條指令,是一個非常小的記憶體空間,幾乎可以忽略不記。
3)、這塊記憶體區域很小,它是當前線程所執行的位元組碼的行號指示器,位元組碼解釋器通過改變這個計數器的值來選取下一條需要執行的位元組碼指令。
4)、如果執行的是一個Native方法,那這個計數器是空的。
7、方法區:
方法區(Method Area)與 Java 堆一樣,是所有線程共用的記憶體區域。
靜態變數、常量、類信息(構造方法、介面定義)、運行時的常量池存在方法區中,但是實例變數存在堆記憶體中和方法區無關
8、棧:(先進後出、後進先出)數據結構
定義:棧(stack)又名堆棧,它是一種運算受限的線性表。限定僅在表尾進行插入和刪除操作的線性表。這一端被稱為棧頂,相對地,把另一端稱為棧底。向一個棧插入新元素又稱作進棧、入棧或壓棧,它是把新元素放到棧頂元素的上面,使之成為新的棧頂元素;從一個棧刪除元素又稱作出棧或退棧,它是把棧頂元素刪除掉,使其相鄰的元素成為新的棧頂元素。
程式=數據結構+演算法
程式執行方法,就是靠棧來調用,最先把main()方法壓在棧的底部,其它方法在上面,等到main()出棧程式執行也就結束了。
所以棧是不存在垃圾回收問題
9、堆
Heap,一個JVM只有一個堆記憶體,堆記憶體的大小是可以調節的
類載入器讀取了類文件後,一般會把類、方法、常量、變數,保存我們所有引用類型的真實對象
堆記憶體中分成三個區域:
1)、新生區(伊甸區)
2)、養老區
3)、永久存儲區
所有GC垃圾回收是在堆里的伊甸區和養老區
jdk8後把永久區名稱改為元空間
新生區:
類:誕生和成長的地方,甚至死亡
伊甸區:所有對象都是在這裡new出來的,即實例化
幸存區(0 1):
養老區:
永久區:這個區域常駐記憶體的,用來存放攜帶的class對象,interface元數據,存儲的是java運行時的一些環境或類信息,這個區域不存在垃圾回收
jdk1.6:永久代、常量池在方法區
jdk1.7:永久代、但是慢慢的退化,常量池在堆中
jdk1.8之後:無永久代、常量池在元空間
OOM定義:OOM,全稱“Out Of Memory”,翻譯成中文就是“記憶體用完了”,來源於java.lang.OutOfMemoryError。看下關於的官方說明: Thrown when the Java Virtual Machine cannot allocate an object because it is out of memory, and no more memory could be made available by the garbage collector. 意思就是說,當JVM因為沒有足夠的記憶體來為對象分配空間並且垃圾回收器也已經沒有空間可回收時,就會拋出這個error(註:非exception,因為這個問題已經嚴重到不足以被應用處理)。
遇到OOM問題:
參考:https://www.cnblogs.com/zhoading/p/10249302.html
(1)調堆記憶體大小;
修改堆的大小:
說明:
-Xms:20M 初始化堆記憶體大小
-Xmn:20M 堆記憶體最大值
-Mmn:10M 新生代記憶體設置
-XX:+PrintGcDetails 用於列印GC的日誌信息
-verbose:gc 用於查看Java垃圾收集的結果
idea界面:
(2)分析記憶體
分析堆記憶體工具:MAT(eclipse)、Jprofiler(idea)
MAT、Jprofiler作用:快速分析Dump記憶體文件,快速定位記憶體泄漏
VM參數:https://www.cnblogs.com/redcreen/archive/2011/05/04/2037057.html
要在idea安裝插件Jprofiler
(1)安裝:https://www.cnblogs.com/javabg/p/11499098.html
(2)使用:https://segmentfault.com/a/1190000021881331
10、GC(垃圾回收)
GC的作用區域:方法區,堆
JVM在進行GC時,並不是三個統一回收,大部分時候,回收新時代
年輕代:存活率低-》複製演算法
幸存區(form,to------》誰空誰是to)
老年區:存活率大-》標記清除演算法(記憶體碎片不是太多)、標記壓縮混合實現
GC兩種類:輕GC(普通的GC)、重GC(全局GC)
GC的演算法:標記清除法、標記整理、複製演算法、引用計數法
參考:https://blog.csdn.net/qq_21383435/article/details/80473540
總結:
記憶體效率:複製演算法>標記清除演算法>標記壓縮演算法
記憶體整齊度:複製演算法=標記壓縮演算法>標記清除演算法
記憶體利用率:標記清除演算法=標記壓縮演算法>複製演算法
11、舉例
(1)JMM(java Memory Model)-》Java記憶體模型
1)定義:(java Memory Model)-》Java記憶體模型
2)作用:緩存一致性協議,用於定義數據讀寫的規則(遵循)
參考:https://blog.csdn.net/zjcjava/article/details/78406330
3)如何學習?
面試題:https://www.cnblogs.com/wjh123/p/11094622.html