柚子快報邀請碼778899分享:JVM概述
柚子快報邀請碼778899分享:JVM概述
JVM概述
1、一些性能上的問題
我好好運(yùn)行的線上系統(tǒng)突然間卡死了,系統(tǒng)無法訪問,當(dāng)然這個原因非常多;想解決線上的JVM GC問題卻無從下手;新的項(xiàng)目上線了,對于各種JVM參數(shù)的設(shè)置一臉茫然,全部直接默認(rèn);
什么是Java虛擬機(jī)(JVM)?
? JVM(Java Virtual Machine),是一種能夠執(zhí)行Java字節(jié)碼的虛擬機(jī)。
? JVM是Java平臺的基石,Java應(yīng)用服務(wù)器實(shí)質(zhì)是JVM的一種擴(kuò)展,而Java應(yīng)用程序則運(yùn)行在JVM之上。Java虛擬機(jī)屏蔽了與具體操作系統(tǒng)平臺相關(guān)的信息,使得Java程序只需生成在Java虛擬機(jī)上運(yùn)行的目標(biāo)代碼(字節(jié)碼),就可以在多種平臺上不加修改地運(yùn)行。JVM在執(zhí)行字節(jié)碼時,實(shí)際上最終還是把字節(jié)碼解釋成具體平臺上的機(jī)器指令執(zhí)行。
? JVM是Java跨平臺的核心機(jī)制,它主要由類加載器、運(yùn)行時數(shù)據(jù)區(qū)、執(zhí)行引擎、本地方法接口等幾個部分組成。JVM的主要職責(zé)包括加載代碼、校驗(yàn)代碼、執(zhí)行代碼、輸出執(zhí)行結(jié)果等。當(dāng)Java編譯器完成了源代碼文件(.java)的編譯工作之后,就生成了能被Java虛擬機(jī)識別的字節(jié)碼文件(.class)。JVM在執(zhí)行這些字節(jié)碼文件時,需要進(jìn)行加載、鏈接、初始化,然后調(diào)用相應(yīng)的方法。
2、Java語言及Java生態(tài)圖
2.1、OracleJDK與OpenJDK什么關(guān)系?
? OracleJDK可以視為OpenJDK的一個衍生版本。這是因?yàn)镺racle公司在2006年收購了Sun Microsystems,從而獲得了Java的知識產(chǎn)權(quán)和相關(guān)技術(shù)。隨后,Oracle基于OpenJDK進(jìn)行開發(fā),并在其基礎(chǔ)上發(fā)布了OracleJDK。
? OpenJDK是Java語言的一個開源實(shí)現(xiàn),項(xiàng)目肇始于2006年SUN公司在Java One大會上對Java的開源決定和承諾,并于2009年4月正式對公眾發(fā)布。它遵循GPL協(xié)議,是Java社區(qū)的核心項(xiàng)目,由全球各地的開發(fā)者共同參與開發(fā)和維護(hù)。
? 而OracleJDK在OpenJDK的基礎(chǔ)上添加了一些商業(yè)功能和工具,例如Java Mission Control、Java Flight Recorder和商業(yè)支持等。此外,OracleJDK還包含了一些與Oracle相關(guān)的特性,比如Oracle Advanced Compression和Oracle Real Application Testing。這使得OracleJDK在功能和工具方面相較于OpenJDK更為豐富。
? 總的來說呢,OracleJDK和OpenJDK都是Java開發(fā)工具包的重要組成部分,它們之間的關(guān)系是OracleJDK在OpenJDK的基礎(chǔ)上進(jìn)行了商業(yè)化的擴(kuò)展和優(yōu)化。這種關(guān)系使得開發(fā)者可以根據(jù)項(xiàng)目需求選擇適合的JDK版本。
2.2、JDK和JVM是什么關(guān)系?
如何理解Java是一個跨平臺的語言?
? “一次編譯到處運(yùn)行”,當(dāng)java源代碼成功編譯成字節(jié)碼之后,如果想在不同的平臺上運(yùn)行的話就不需要再次編譯了,但是,就現(xiàn)在來講這個并不能說是一個特點(diǎn)了,Python、PHP、Perl、Ruby等有強(qiáng)大的編譯器??缙脚_已經(jīng)成為了入門語言的必選特性了。
如何理解JVM是跨語言平臺?
? Java虛擬機(jī)根本不關(guān)心運(yùn)行在其內(nèi)部的程序到底是使用什么編程語言編寫的,它只關(guān)心“字節(jié)碼文件”
? 雖然Java不是最強(qiáng)大的語言,但是JVM是最強(qiáng)大的虛擬機(jī)
Java不存在內(nèi)存溢出?內(nèi)存泄漏?
? 想多了,當(dāng)然不是的。
內(nèi)存溢出,主要發(fā)生在當(dāng)Java程序試圖使用比系統(tǒng)給它更多的內(nèi)存時就會內(nèi)存溢出。系統(tǒng)就給它了那些,它還想超出一部分。這可能是因?yàn)槌绦蛑械哪骋粋€部分不斷地申請新的內(nèi)存空間,而沒有適當(dāng)?shù)尼尫挪辉傩枰膬?nèi)存,當(dāng)JVM的堆內(nèi)存達(dá)到了最大的限制時,就會拋出OutOfMemoryError的錯誤,這就是內(nèi)存溢出;
Java中最常見的就是堆內(nèi)存溢出,Java程序的對象都存儲在堆內(nèi)存中,當(dāng)堆內(nèi)存中的對象數(shù)超過了JVM所分配的最大堆內(nèi)存容量時,就會發(fā)生堆內(nèi)存溢出。除了堆內(nèi)存溢出有外,還有棧內(nèi)存溢出,通常時由于方法調(diào)用的遞歸層次太深而導(dǎo)致棧內(nèi)存耗盡。 內(nèi)存泄漏,是另一種情況,當(dāng)應(yīng)用程序持有不再需要的對象仍然被持有,無法被垃圾回收器釋放,導(dǎo)致內(nèi)存占用持續(xù)增加,最終耗盡可用內(nèi)存。
在Java中,最常見的內(nèi)存泄漏是由于對象的引用未被釋放而導(dǎo)致。比如,當(dāng)一個對象持有了對另一個對象的引用,而這個引用在程序中不再需要時卻未被釋放,這就會導(dǎo)致內(nèi)存泄漏。內(nèi)存泄漏可能是由于程序邏輯錯誤、不良的對象引用管理或者使用第三方庫時未正確的釋放資源所導(dǎo)致的。
那么怎么解決內(nèi)存的溢出和泄漏呢?
對于內(nèi)存的溢出,可以通過增加堆內(nèi)存大?。ㄟ@個就得去調(diào)JVM的參數(shù)了,你再使用默認(rèn)的就不能滿足系統(tǒng)需求了)或者優(yōu)化程序設(shè)計(jì)來減少內(nèi)存的使用。對于內(nèi)存的泄漏,需要通過代碼審查和分析來找出沒有被釋放引用的地方,并保證在不再需要對象時及時釋放對其的引用。使用Java內(nèi)置的垃圾回收器也能幫助檢測和處理內(nèi)存泄漏問題。
各種JVM
Sun Classic VM -->解釋型 Exact VM --> Solaris SUN公司的 HotSpot VM BEA 的 JRockit --> 不包含解釋器,服務(wù)器端,JMC IBM 的 J9 KVM和CDC/CLDC Hotspot Azul VM Liquid VM Apache Harmony Microsoft JVM TaobaoJVM Graal VM --> 2018年,“Run Programs Faster Anywhere” Dalvik VM 其他JVM: Java Card VM、Squawk VM、JavaInJava、Maxine VM、Jikes RVM、IKVM.NET、Jam VM、Cacao VM、Sable VM、Kaffe、Jelatine JVM、Nano VM、MRP、Moxie JVM
2.3、JVM的生命周期
? Java虛擬機(jī)的啟動是通過引導(dǎo)類加載器(bootstrap class loader)創(chuàng)建一個初始類(initial class)來完成的,這個類是由虛擬機(jī)的具體實(shí)現(xiàn)指定的。
虛擬機(jī)的退出有以下幾種情況:
某線程調(diào)用Runtime類或者System類的exit方法,或Runtime類的halt方法,并且Java安全管理器也允許這次exit或halt的操作;程序正常的執(zhí)行結(jié)束;程序在執(zhí)行過程中遇到了異?;蝈e誤而異常終止;由于操作系統(tǒng)出現(xiàn)錯誤而導(dǎo)致Java虛擬機(jī)進(jìn)程終止;
2.4、重點(diǎn)說一下HotSpot
SUN的JDK版本從1.3.1開始運(yùn)用HotSpot虛擬機(jī), 2006年底開源,主要使用C++實(shí)現(xiàn),JNI接口部分用C實(shí)現(xiàn)。HotSpot是較新的Java虛擬機(jī),使用JIT(Just in Time)編譯器,可以大大提高Java運(yùn)行的性能。Java原先是把源代碼編譯為字節(jié)碼在虛擬機(jī)執(zhí)行,這樣執(zhí)行速度較慢。而HotSpot將常用的部分代碼編譯為本地(原生,native)代碼,這樣顯著提高了性能。HotSpot JVM 參數(shù)可以分為規(guī)則參數(shù)(standard options)和非規(guī)則參數(shù)(non-standard options)。 規(guī)則參數(shù)相對穩(wěn)定,在JDK未來的版本里不會有太大的改動。 非規(guī)則參數(shù)則有因升級JDK而改動的可能。
2.5、JVM架構(gòu)圖
這個架構(gòu)可以分成三層看:
最上層:javac編譯器將編譯好的字節(jié)碼class文件,通過java類裝載器執(zhí)行機(jī)制,把對象或class文件存放在jvm劃分內(nèi)存區(qū)域。中間層:稱為Runtime Data Area,主要是在Java代碼運(yùn)行時用于存放數(shù)據(jù)的,從左往右為方法區(qū)(永久代、元數(shù)據(jù)區(qū))、堆(共享,GC回收對象區(qū)域)、棧、寄存器、本地方法棧(私有)。最下層,解釋器、JIT(just in time)編譯器和GC(Garbage Collection,垃圾回收器);
JVM的幾塊知識
柚子快報邀請碼778899分享:JVM概述
推薦鏈接
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場。
轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。