一聊到JVM,首先要想到爲什麼需要虛擬機
因爲java的跨平臺,就是通過虛擬機來實現的
JVM的原理
1。類加載機制
jvm類加載機制:加載,驗證,準備,解析,初始化
類加載機制需要知道的是雙親委派,會先把請求委派給父類加載
Bootstrap Classloader>Extension ClassLoader>Application Classloader
如何驗證呢:自己創建一個class類,如創建一個User
User.class.getClassLoader().toString() 輸出appClassloader
User.calss.getClassLoader().getParent.toString() 輸出ExtClassLoader
這邊不能輸出bootstrap ClassLoader 會報錯NullPointerException
好處:防止內存出現多分同樣的字節碼,保證類的唯一性
如何打破雙親委派,繼承ClassLoader,重寫findClass,loadClass方法
2。內存管理
每一個JVM都會包含方法區,java堆,java棧,本地方法棧,指令計數器
方法區和java堆是線程共享的
java棧,本地方法棧,指令計數器是每一個線程都會有的,是線程隔離的
如何撐爆堆呢?死循環,會拋出OutOfMemoryError
如何撐爆棧(stack)遞歸調用,會拋出StackOverFlowError
3。垃圾回收
GC(重災區)
要知道gc的幾個算法,標記清除算法,複製算法,標記整理算法
jdk1.7和jdk1.8的關於gc的永久帶的區別,1.8把永久帶不再放到堆中,放到了磁盤中
什麼時候會gc?
當對象沒有被引用到的時候,可以自己gc,System.gc()
GC的時候對象會被分爲強引用,軟引用,弱引用,虛引用
finalize()引用了對象的話,可以使對象這一次gc的時候不會被回收
後面就聊一下關於新生代,老年代和永久帶
我的理解是:年輕代存放的是新的對象,就是引用次數比較少的,隨着gc,會給這些對象標記被引用的次數,次數達到一定的量會被放到老年代中,所以兩個代的算法是不一樣的,年輕代用的是複製算法,老年代用的是標記整理算法。
新生代的默認的收集器:Paraller Scavenge
老年代的默認的收集器:Paraller Old
還有就是如何給jvm調參數,idea是tomcat中的VM options