->java體系結(jié)構(gòu)
1肚菠、java體系結(jié)構(gòu):由java語言舔箭,class文件,java api和虛擬機組成蚊逢。
2、java運行機制:a.源碼編譯為.class文件(java會被編譯器編譯為class字節(jié)碼文件)箫章;b.jvm的類加載器裝載calss文件烙荷;c.jvm找到main()入口,開始運行class(二進制字節(jié)碼檬寂,JNI接口是java本地接口终抽,裝載class文件);d.jvm開始垃圾回收桶至。
3昼伴、類加載器:分為4種:啟動類加載器(負責加載JDK中的核心類庫);擴展類加載器(負責加載Java的擴展類庫)镣屹;系統(tǒng)類加載器(負責加載應用程序classpath目錄下所有jar和class文件)圃郊;自定義加載器(加載自己定義的class)。
以上除了第一種加載器女蜈,其他加載器最終都依賴于第一種啟動類加載器(也就是所說的雙親委派模式持舆,將加載任務委派給他的雙親加載器)色瘩。
加載器具體工作步驟:
a、加載:尋找并導入Class文件的二進制信息逸寓,在堆中生成class對象
b居兆、連接:進行驗證、準備和解析(通過安全機制進行安全驗證)
? ? 1)驗證:確保導入類型的正確性
? ? 2)準備:為類型分配內(nèi)存并初始化為默認值
? ? 3)解析:將字符引用解析為直接引用
c竹伸、初始化:調(diào)用Java代碼泥栖,初始化類變量為指定初始值,如果子類初始化勋篓,會先初始化其父類(jvm調(diào)用<clinit>方法初始化類變量和靜態(tài)初始化方法)
4聊倔、java安全性:主要由類裝載器結(jié)構(gòu)(定義信任類庫邊界,保護域生巡,雙親委派模式)耙蔑、
class文件檢驗器(4次檢驗:class文件結(jié)構(gòu),類型數(shù)據(jù)的語意檢查孤荣,字節(jié)碼驗證甸陌,符號引用的驗證)、
基于內(nèi)置的jvm及語言的安全特性(安全類型轉(zhuǎn)換盐股,沒有指針钱豁,自動垃圾回收,數(shù)組界限疯汁,null引用)牲尺、
安全管理器(定義了“沙盒”的外部邊界)和JAVA API(api執(zhí)行活動會先經(jīng)過安全管理器,找到再執(zhí)行)組成幌蚊。
4.1谤碳、jvm內(nèi)存模型:jvm中堆可稱為主存,每一個線程都有自己的工作內(nèi)存溢豆,下圖解釋了線程間如何通信的:
->java虛擬機
5蜒简、java虛擬機:內(nèi)部有兩種線程:守護線程(jvm自己使用,處理gc等)漩仙;非守護線程(執(zhí)行mian()的初始線程)搓茬。jvm的內(nèi)部體系結(jié)構(gòu)如下:
其中方法區(qū)(存運行時常量池、已被jvm加載的類信息队他、常量卷仑、靜態(tài)變量、即時編譯器編譯后的代碼等數(shù)據(jù))
和堆(存創(chuàng)建的對象實例)是線程共享的(一個jvm實例有一個方法區(qū)和堆麸折,需要gc回收锡凝,會有OutOfMemoryError異常)。
JAVA棧(棧幀:存的是局部變量磕谅、參數(shù)私爷、返回值雾棺、對象引用等,會有StackOverflowError異常)衬浑、PC寄存器(存下一條執(zhí)行的指令)
和本地方法棧(本地方法)是一個線程獨享的(隨線程結(jié)束而結(jié)束)捌浩。
6、數(shù)據(jù)類型:
7工秩、class文件:一個calss文件都有一個常量池(保存所有的引用符號)
8尸饺、垃圾回收機制(gc):釋放不被引用的對象的堆空間和堆碎塊(方法區(qū)中回收廢棄常量和無用的類)。判斷對象是否存活的算法有:
a.引用計數(shù)算法(堆的對象實例都有一個引用計數(shù)助币,被創(chuàng)建時為1浪听,任何其它變量被賦值為這個對象的引用+1,引用計數(shù)=0時可被回收眉菱。優(yōu)點:速度快迹栓;缺點:無法檢測出循環(huán)引用)。
b.可達性分析算法(把GC Roots的對象作為起始點俭缓,開始向下搜索克伊,當一個對象到GC Roots沒有任何引用,則不存活华坦。被第一次標記愿吹,再次刷選,對象是否有finalize()惜姐,如果finalize()中沒復活犁跪,則被第二次標記,然后才會被回收歹袁】姥埽可作為GC Roots的對象包括下面幾種:
??1) 虛擬機棧中引用的對象(棧幀中的本地變量表);
??2) 方法區(qū)中類靜態(tài)屬性引用的對象宇攻;
??3) 方法區(qū)中常量引用的對象惫叛;
??4) 本地方法棧中JNI(Native方法)引用的對象逞刷。
)。
java中引用分為:強引用(類似Object obj = new Object()妻熊,強引用還在夸浅,就算存活)、軟引用(如果系統(tǒng)要內(nèi)存溢出扔役,弱引用將會在第二次回收中被回收)帆喇、弱引用(下次回收前被回收,不管內(nèi)存)亿胸、虛引用:
常用的垃圾收集算法:
a.標記-清除算法:從根集合(GC Roots)進行掃描坯钦,對存活的對象進行標記预皇,標記完畢后,再掃描整個空間中未被標記的對象婉刀,進行回收(缺點:造成內(nèi)存碎片)吟温。
b.復制算法:把堆分為對象區(qū)和空閑區(qū),當對象區(qū)滿了突颊,掃描活動對象鲁豪,把它們copy到空閑區(qū),兩個區(qū)就倒了過來(由于copy對象到空閑律秃,所以不會造成內(nèi)存碎片)爬橡。
c.標記-整理算法:和標記-清除一樣,回收后多了一步操作,會將所有的存活對象往左端空閑空間移動棒动,并更新對應的指針(解決了內(nèi)存碎片)糙申。
d.分代收集算法:根據(jù)對象存活周期把內(nèi)存分為新生代(生命周期短的,如局部變量等船惨,在堆中)柜裸、老年代(周期長的,如緩存對象掷漱、單例對象等粘室,在堆中)和永久代(靜態(tài)文件,如Java類卜范、方法等衔统,在方法區(qū)中,jdk1.8以后海雪,改為元數(shù)據(jù)區(qū)锦爵,使用本地內(nèi)存了)。
新生代算法:內(nèi)存按照8:1:1的比例分為一個eden區(qū)和兩個survivor(survivor0,survivor1)區(qū)奥裸。大部分對象在eden险掀,回收時,eden存活對象copy至survivor0湾宙,清空eden樟氢;當survivor0也滿了,再把eden侠鳄、survivor0存活對象copy至survivor1埠啃,清空eden、survivor0伟恶,再把survivor0和survivor1交換碴开。
以上是新生代回收,也叫Minor GC。(頻率較高)
老年代算法:當survivor1也滿了潦牛,把存活對象copy至老年代眶掌,觸發(fā)一次Full GC(新生代、老年代都回收)巴碗。其中內(nèi)存比新生代也大很多(大概比例是1:2)朴爬。
永久代算法:回收廢棄常量(可達性分析算法標記)、無用的類(該類所有的實例都已經(jīng)被回收)良价。
收集器:
Serial收集器(復制算法)
新生代單線程收集器寝殴,標記和清理都是單線程,優(yōu)點是簡單高效明垢。是client級別默認的GC方式蚣常,可以通過-XX:+UseSerialGC來強制指定。
Serial Old收集器(標記-整理算法)
老年代單線程收集器痊银,Serial收集器的老年代版本抵蚊。
ParNew收集器(停止-復制算法)
新生代收集器,可以認為是Serial收集器的多線程版本,在多核CPU環(huán)境下有著比Serial更好的表現(xiàn)溯革。
Parallel Scavenge收集器(停止-復制算法)
并行收集器贞绳,追求高吞吐量,高效利用CPU致稀。吞吐量一般為99%冈闭, 吞吐量= 用戶線程時間/(用戶線程時間+GC線程時間)。適合后臺應用等對交互相應要求不高的場景抖单。是server級別默認采用的GC方式萎攒,可用-XX:+UseParallelGC來強制指定,用-XX:ParallelGCThreads=4來指定線程數(shù)矛绘。
Parallel Old收集器(停止-復制算法)
Parallel Scavenge收集器的老年代版本耍休,并行收集器,吞吐量優(yōu)先货矮。
CMS(Concurrent Mark Sweep)收集器(標記-清理算法)
高并發(fā)羊精、低停頓,追求最短GC回收停頓時間囚玫,cpu占用比較高喧锦,響應時間快,停頓時間短抓督,多核cpu 追求高響應時間的選擇裸违。
G1收集器(jdk1.7以后支持,試圖取代CMS)
G1適用于新生代和老年代本昏,而CMS只適用于老年代。
9枪汪、監(jiān)聽器:支持互斥和協(xié)作兩種線程涌穆。監(jiān)聽器模型如下:
可以使用如下方法讓線程等待/喚醒:
10怔昨、jvm配置參數(shù):分為三類,
a.跟蹤參數(shù)(跟蹤監(jiān)控jvm狀態(tài)):-XX:+PrintGC或-verbose:gc參數(shù)(打印GC簡要信息)宿稀;-XX:+PrintGCDetails參數(shù)(打印GC的詳細信息以及堆使用詳細信息)趁舀;-Xloggc:log/gc.log(外部文件記錄GC的日志);-XX:+TraceClassLoading(監(jiān)控類的加載)祝沸。
b.堆分配參數(shù)(分配堆內(nèi)存):-Xmx(最大堆)矮烹;-Xms(最小堆);Xmn(新生代大姓秩瘛)奉狈;-XX:PermSize(永久區(qū)初始值) -XX:MaxPermSize(永久區(qū)最大值)。
c.棧分配參數(shù)(分配棧內(nèi)存):-Xss(棧大猩蟆)仁期。
(官方推薦新生代占堆的3/8,幸存代占新生代的1/10)
11竭恬、jvm性能監(jiān)控工具:jps(JVM 進程狀況工具)跛蛋;jstat(JVM 統(tǒng)計信息監(jiān)控工具);jinfo(Java 配置信息)痊硕;jmap(Java 內(nèi)存映射工具)赊级;jhat(JVM 堆快照分析工具);jstack(Java 堆棧跟蹤工具)岔绸;(參考:https://www.sohu.com/a/199863043_827544)