自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

程序員進(jìn)階架構(gòu)師必看的面試重災(zāi)區(qū):JVM整體架構(gòu)、內(nèi)存模型與調(diào)優(yōu)實(shí)戰(zhàn)

開發(fā) 架構(gòu)
在互聯(lián)網(wǎng)這個行業(yè)中,誰掌握了底層的核心知識,誰就能在激烈的競爭環(huán)境中脫穎而出。JVM看起來很難,只要你掌握了學(xué)習(xí)JVM的規(guī)律和方法,吃透它,其實(shí)很簡單的。

從今天開始,我們正式開始《架構(gòu)師進(jìn)階系列》技術(shù)文的更新,在《架構(gòu)師進(jìn)階系列》中,我們首先一起來探討有關(guān)JVM的知識。

很多小伙伴都認(rèn)為JVM的知識很難,很枯燥,不知道該如何學(xué)習(xí),買了很多關(guān)于JVM的書籍,看了沒幾頁就看不下去了,隨后書籍被放到書架里,很長一段時間內(nèi)成為了“吃灰”的擺件。

其實(shí),在互聯(lián)網(wǎng)這個行業(yè)中,誰掌握了底層的核心知識,誰就能在激烈的競爭環(huán)境中脫穎而出。JVM看起來很難,只要你掌握了學(xué)習(xí)JVM的規(guī)律和方法,吃透它,其實(shí)很簡單的。

PS:后續(xù)星球帶著大家一起從零開始設(shè)計并手寫JVM源碼。

文章總體結(jié)構(gòu)

本文中,我們將按照如下結(jié)構(gòu)介紹JVM的整體架構(gòu)和調(diào)優(yōu)參數(shù)。

JVM的分類

這里,我們先來說說什么是VM吧,VM的中文含義為:虛擬機(jī),指的是使用軟件的方式模擬具有完整硬件系統(tǒng)功能、運(yùn)行在一個完全隔離環(huán)境中的完整計算機(jī)系統(tǒng),是物理機(jī)的軟件實(shí)現(xiàn)。

常用的虛擬機(jī)有:VMWare、Virtual Box,Java Virtual Machine(JVM,Java虛擬機(jī))。

這里,我們重點(diǎn)聊的就是JVM,Java虛擬機(jī)??聪聢D。

這張圖看起來還是比較簡單的,JVM運(yùn)行于操作系統(tǒng)之上,操作系統(tǒng)是運(yùn)行在計算機(jī)硬件上的。

關(guān)于JVM,其實(shí)有很多大廠開發(fā)了不同版本的JVM,比較知名的有:Sun HotSpot VM、BEA JRockit VM、IBM J9 VM、 Azul VM、 Apache Harmony、 Google Dalvik VM、 Microsoft JVM等等。

現(xiàn)在使用的比較多的JDK8版本就是Sun HotSpot VM與BEA JRockit VM合并之后開發(fā)出的JDK版本。

JVM的構(gòu)成

JVM主要由三個子系統(tǒng)構(gòu)成,分別為:類加載器子系統(tǒng)、運(yùn)行時數(shù)據(jù)區(qū)(內(nèi)存結(jié)構(gòu))和字節(jié)碼執(zhí)行引擎。

為了更好的理解JVM,我們來看一下JVM的全貌圖。

當(dāng)我們開發(fā)Java程序時,首先會編寫.java文件,之后,會將.java文件編譯成.class文件。

JVM中,會通過類裝載子系統(tǒng)將.class文件的內(nèi)容裝載到JVM的運(yùn)行時數(shù)據(jù)區(qū),而JVM的運(yùn)行時數(shù)據(jù)區(qū)又會分為:方法區(qū)、堆、棧、本地方法棧和程序計數(shù)器 幾個部分。

在裝載class文件的內(nèi)容時,會將class文件的內(nèi)容拆分為幾個部分,分別裝載到JVM運(yùn)行時數(shù)據(jù)區(qū)的幾個部分。其中,值得注意的是:程序計數(shù)器的作用是:記錄程序執(zhí)行的下一條指令的地址。

方法區(qū)也叫作元空間,主要包含了:運(yùn)行時常量池、類型信息、字段信息、方法信息、類加載器的引用、對應(yīng)的Class實(shí)例的引用等信息。

在JVM中,程序的執(zhí)行是通過執(zhí)行引擎進(jìn)行的,執(zhí)行引擎會調(diào)用本地方法的接口來執(zhí)行本地方法庫,進(jìn)而完成整個程序邏輯的執(zhí)行。

我們常說的垃圾收集器是包含在執(zhí)行引擎中的,在程序的運(yùn)行過程中,執(zhí)行引擎會開啟垃圾收集器,并在后臺運(yùn)行,垃圾收集器會不斷監(jiān)控程序運(yùn)行過程中產(chǎn)生的內(nèi)存垃圾信息,并根據(jù)相應(yīng)的策略對垃圾信息進(jìn)行清理。

這里,大家需要注意的是:棧、本地方法棧和程序計數(shù)器是每個線程運(yùn)行時獨(dú)占的,而方法區(qū)和堆是所有線程共享的。所以,棧、本地方法棧和程序計數(shù)器不會涉及線程安全問題,而方法區(qū)和堆會涉及線程安全問題。

方法區(qū)(元空間)

很多小伙伴一看到方法區(qū)三個字,腦海中的第一印象可能是存儲方法的地方吧。

實(shí)則不然,方法區(qū)的另一個名字叫作元空間,相信不少小伙伴或多或少的聽說過元空間。這個區(qū)域是JDK1.8中劃分出來的。主要包含:運(yùn)行時常量池、類型信息、字段信息、方法信息、類加載器的引用、對應(yīng)的Class實(shí)例的引用等信息。方法區(qū)中的信息能夠被多個線程共享。

例如,在程序中聲明的常量、靜態(tài)變量和有關(guān)于類的信息等的引用,都會存放在方法區(qū),而這些引用所指向的具體對象 一般都會在堆中開辟單獨(dú)的空間進(jìn)行存儲,也可能會在直接內(nèi)存中進(jìn)行存儲。

堆中主要存儲的是實(shí)際創(chuàng)建的對象,也就是會存儲通過new關(guān)鍵字創(chuàng)建的對象,堆中的對象能夠被多個線程共享。堆中的數(shù)據(jù)不需要事先明確生存期,可以動態(tài)的分配內(nèi)存,不再使用的數(shù)據(jù)和對象由JVM中的GC機(jī)制自動回收。對JVM的性能調(diào)優(yōu)一般就是對堆內(nèi)存的調(diào)優(yōu)。

Java中基本類型的包裝類:Byte、Short、Integer、Long、Float、Double、Boolean、Character類型的數(shù)據(jù)是存儲在堆中的。

堆一般會被分成年輕代和老年代。而年輕代又會被進(jìn)一步分為1個Eden區(qū)和2個Survivor區(qū)。在內(nèi)存分配上,如果保持默認(rèn)配置的話,年輕代和老年代的內(nèi)存大小比例為1 : 2,年輕代中的1個Eden區(qū)和2個Survivor區(qū)的內(nèi)存大小比例為:8 : 1 : 1。

棧一般又叫作線程?;蛱摂M機(jī)棧,一般存儲的是局部變量。在Java中,每個線程都會有一個單獨(dú)的棧區(qū),每個棧中的元素都是私有的,不會被其他的棧所訪問。棧中的數(shù)據(jù)大小和生存期都是確定的,存取速度比較快。

在Java中,所有的基本數(shù)據(jù)類型(byte、short、int、long、float、double、boolean、char)和引用變量(對象引用)都是在棧中的。一般情況下,線程退出或者方法退出時,棧中的數(shù)據(jù)會被自動清除。

程序在執(zhí)行過程中,會在棧中為不同的方法創(chuàng)建不同的棧幀,在棧幀中又包含了:局部變量表、操作數(shù)棧、動態(tài)鏈接和方法出口。

關(guān)于局部變量表、操作數(shù)棧、動態(tài)鏈接和方法出口的具體作用,會在《架構(gòu)師進(jìn)階系列》中的后續(xù)文章中詳細(xì)闡述。

棧中一般會存儲對象的引用,這些引用所指向的具體對象一般都會在堆中開辟單獨(dú)的地址空間進(jìn)行存儲,也有可能存儲在直接內(nèi)存中。

注意:這里說的是這些引用所指向的具體對象一般都會在堆中開辟單獨(dú)的地址空間進(jìn)行存儲,也有可能存儲在直接內(nèi)存中。

因為在JVM中,如果開啟了逃逸分析和標(biāo)量替換,則可能不會再在堆上創(chuàng)建對象,可能會將對象直接分配到棧上,也可能不再創(chuàng)建對象,而是進(jìn)一步分解對象中的成員變量,將其直接在棧上分配空間并賦值。

本地方法棧

本地方法棧相對來說比較簡單,就是保存native方法進(jìn)入?yún)^(qū)域的地址。

例如,在Java中創(chuàng)建線程,調(diào)用Thread對象的start()方法時,會通過本地方法start0()調(diào)用操作系統(tǒng)創(chuàng)建線程的方法。此時,本地方法棧就會保存start0()方法進(jìn)入?yún)^(qū)域的內(nèi)存地址。

程序計數(shù)器

程序計數(shù)器也叫作PC計數(shù)器,只要存儲的是下一條將要執(zhí)行的命令的地址。

JVM調(diào)優(yōu)實(shí)戰(zhàn)

在JVM中,主要是對堆(新生代)、方法區(qū)和棧進(jìn)行性能調(diào)優(yōu)。各個區(qū)域的調(diào)優(yōu)參數(shù)如下所示。

  • 堆:-Xms、-Xmx
  • 新生代:-Xmn
  • 方法區(qū)(元空間):-XX:MetaspaceSize、-XX:MaxMetaspaceSize
  • 棧(線程):-Xss

為了更加直觀的表述,我們可以將JVM的內(nèi)存區(qū)域和對應(yīng)的調(diào)優(yōu)參數(shù)總結(jié)成下圖所示。

在設(shè)置JVM啟動參數(shù)時,需要特別注意方法區(qū)(元空間)的參數(shù)設(shè)置。

關(guān)于方法區(qū)(元空間)的JVM參數(shù)主要有兩個:-XX:MetaspaceSize和-XX:MaxMetaspaceSize。

-XX:MetaspaceSize: 指的是方法區(qū)(元空間)觸發(fā)Full GC的初始內(nèi)存大?。ǚ椒▍^(qū)沒有固定的初始內(nèi)存大小),以字節(jié)為單位,默認(rèn)為21M。達(dá)到設(shè)置的值時,會觸發(fā)Full GC,同時垃圾收集器會對這個值進(jìn)行修改。

如果在發(fā)生Full GC時,回收了大量內(nèi)存空間,則垃圾收集器會適當(dāng)降低此值的大?。蝗绻诎l(fā)生Full GC時,釋放的空間比較少,則在不超過設(shè)置的-XX:MetaspaceSize值或者在沒設(shè)置-XX:MetaspaceSize的值時不超過21M,適當(dāng)提高此值。

-XX:MaxMetaspaceSize: 指的是方法區(qū)(元空間)的最大值,默認(rèn)值為-1,不受堆內(nèi)存大小限制,此時,只會受限于本地內(nèi)存大小。

最后需要注意的是: 調(diào)整方法區(qū)(元空間)的大小會發(fā)生Full GC,這種操作的代價是非常昂貴的。如果發(fā)現(xiàn)應(yīng)用在啟動的時候發(fā)生了Full GC,則很有可能是方法區(qū)(元空間)的大小被動態(tài)調(diào)整了。

所以,為了盡量不讓JVM動態(tài)調(diào)整方法區(qū)(元空間)的大小造成頻繁的Full GC,一般將-XX:MetaspaceSize和-XX:MaxMetaspaceSize設(shè)置成一樣的值。例如,物理內(nèi)存8G,可以將這兩個值設(shè)置為256M。

最后,我們一起看下在物理內(nèi)存8G的情況下,啟動應(yīng)用程序時,可以設(shè)置的JVM參數(shù)。當(dāng)然,我這里給出的是一些經(jīng)驗值,實(shí)際部署到生產(chǎn)環(huán)境時,需要經(jīng)過壓測找到最佳的參數(shù)值。

  • 啟動SpringBoot
java ‐Xms2048M ‐Xmx2048M ‐Xmn1024M ‐Xss512K ‐XX:MetaspaceSize=256M ‐XX:MaxMetaspaceSize=256M ‐jar xxx.jar
  • 啟動Tomcat(Linux)

在Tomcat bin目錄下catalina.sh文件里配置。

‐Xms2048M ‐Xmx2048M ‐Xmn1024M ‐Xss512K ‐XX:MetaspaceSize=256M ‐XX:MaxMetaspaceSize=256M
  • 啟動Tomcat(Windows)

在Tomcat bin目錄下catalina.bat文件里配置。

‐Xms2048M ‐Xmx2048M ‐Xmn1024M ‐Xss512K ‐XX:MetaspaceSize=256M ‐XX:MaxMetaspaceSize=256M

總結(jié)

今天,我們一起學(xué)習(xí)了JVM的整體架構(gòu)和調(diào)優(yōu)參數(shù),主要包括:JVM的總體結(jié)構(gòu)、JVM的分類、JVM的構(gòu)成和調(diào)優(yōu)參數(shù)。你學(xué)會了嗎?

責(zé)任編輯:姜華 來源: 冰河技術(shù)
相關(guān)推薦

2021-09-06 11:02:17

JVM架構(gòu)調(diào)優(yōu)

2009-10-28 11:05:25

2015-08-03 10:56:22

中國蘋果翻新機(jī)

2014-07-29 14:04:50

程序員

2021-09-30 15:35:04

勒索軟件數(shù)據(jù)安全工具

2021-08-23 06:35:05

勒索軟件惡意軟件安全

2010-12-16 11:05:36

數(shù)學(xué)程序員Google首席Jav

2010-07-10 11:40:15

2012-07-10 10:03:43

2020-09-28 14:29:41

航旅業(yè)網(wǎng)絡(luò)安全漏洞

2015-12-09 15:16:03

架構(gòu)師京東架構(gòu)

2021-11-10 15:00:17

電商平臺網(wǎng)絡(luò)安全“Bot攻擊

2020-04-15 19:53:49

TomcatApache內(nèi)存

2017-11-14 11:00:53

程序員

2017-11-03 13:39:49

WOT峰會

2024-02-18 13:41:16

2022-03-14 14:38:43

互聯(lián)網(wǎng)安全投訴

2009-12-25 11:07:26

架構(gòu)師

2013-06-13 14:29:26

架構(gòu)師程序員

2009-06-04 16:37:20

SOA架構(gòu)師業(yè)務(wù)流程
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號