偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

JVM整體架構(gòu)與調(diào)優(yōu)參數(shù)說明

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

[[421897]]

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

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

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

分享各種編程語言、開發(fā)技術(shù)、分布式與微服務(wù)架構(gòu)、分布式數(shù)據(jù)庫、分布式事務(wù)、云原生、大數(shù)據(jù)與云計(jì)算技術(shù)和滲透技術(shù)。另外,還會(huì)分享各種面試題和面試技巧。

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

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

JVM的分類

這里,我們先來說說什么是VM吧,VM的中文含義為:虛擬機(jī),指的是使用軟件的方式模擬具有完整硬件系統(tǒng)功能、運(yùn)行在一個(gè)完全隔離環(huán)境中的完整計(jì)算機(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ì)算機(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主要由三個(gè)子系統(tǒng)構(gòu)成,分別為:類加載器子系統(tǒng)、運(yùn)行時(shí)數(shù)據(jù)區(qū)(內(nèi)存結(jié)構(gòu))和字節(jié)碼執(zhí)行引擎。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

本地方法棧

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

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

程序計(jì)數(shù)器

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

JVM調(diào)優(yōu)參數(shù)

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

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

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

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

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

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

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

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

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

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

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

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

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

  1. ‐Xms2048M ‐Xmx2048M ‐Xmn1024M ‐Xss512K ‐XX:MetaspaceSize=256M ‐XX:MaxMetaspaceSize=256M 
  • 啟動(dòng)Tomcat(Windows)

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

  1. ‐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é)會(huì)了嗎?歡迎在文末留言說出你的想法,如果你有更好的見解,也可以在文末留言和大家交流。

好了,今天就到這兒吧,我是冰河,我們下期見~~

本文轉(zhuǎn)載自微信公眾號(hào)「冰河技術(shù)」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系冰河技術(shù)公眾號(hào)。

 

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

2010-03-04 10:56:52

JVM參數(shù)

2010-09-25 13:05:07

JVM參數(shù)

2023-11-10 11:23:20

JVM內(nèi)存

2021-11-21 23:03:38

jvm調(diào)優(yōu)虛擬機(jī)

2012-01-10 14:35:08

JavaJVM

2010-09-17 17:02:24

JVM參數(shù)

2017-07-21 08:55:13

TomcatJVM容器

2023-11-11 19:07:23

JVMJava

2011-02-23 10:21:18

ProFTPd參數(shù)

2011-11-28 15:26:40

Nginx配置

2011-02-25 09:56:30

Proftpd

2021-03-17 11:35:11

JVM代碼Java

2010-09-26 13:39:46

JVM調(diào)優(yōu)

2010-09-26 09:08:17

JVM調(diào)優(yōu)

2012-01-10 15:13:56

JavaJVM

2011-02-25 11:29:33

ProFTP參數(shù)

2017-10-13 15:16:38

Java服務(wù)GC參數(shù)

2024-01-15 08:02:07

JVM架構(gòu)內(nèi)存模型

2021-06-03 08:32:18

JVM調(diào)優(yōu)虛擬機(jī)

2017-09-22 15:15:23

jvm調(diào)優(yōu)命令
點(diǎn)贊
收藏

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