最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解JVM中的本機(jī)內(nèi)存跟蹤

 更新時(shí)間:2019年07月07日 14:31:20   投稿:laozhang  
在本文里小編給大家整理了一篇關(guān)于JVM中的本機(jī)內(nèi)存跟蹤的相關(guān)知識(shí)點(diǎn)內(nèi)容,有興趣的朋友們參考學(xué)習(xí)下。

1.概述

有沒(méi)有想過(guò)為什么Java應(yīng)用程序通過(guò)眾所周知的-Xms和-Xmx調(diào)優(yōu)標(biāo)志消耗的內(nèi)存比指定數(shù)量多得多?出于各種原因和可能的優(yōu)化,JVM可以分配額外的本機(jī)內(nèi)存。這些額外的分配最終會(huì)使消耗的內(nèi)存超出-Xmx限制。

在本教程中,我們將列舉JVM中的一些常見(jiàn)內(nèi)存分配源,以及它們的大小調(diào)整標(biāo)志,然后學(xué)習(xí)如何使用本機(jī)內(nèi)存跟蹤監(jiān)視它們。

2.原生分配

堆通常是Java應(yīng)用程序中最大的內(nèi)存使用者,但還有其他人。除了堆之外,JVM還從本機(jī)內(nèi)存中分配出一個(gè)相當(dāng)大的塊來(lái)維護(hù)類的元數(shù)據(jù),應(yīng)用程序代碼,JIT生成的代碼,內(nèi)部數(shù)據(jù)結(jié)構(gòu)等。在下面的部分中,我們將探討其中的一些分配。

2.1. Metaspace(元空間)

為了維護(hù)有關(guān)已加載類的一些元數(shù)據(jù),JVM使用名為Metaspace的專用非堆區(qū)域。在Java 8之前,被稱為PermGen或Permanent Generation。 Metaspace或PermGen包含有關(guān)已加載類的元數(shù)據(jù),而不是它們的實(shí)例,它們保存在堆中。

這里重要的是堆大小配置不會(huì)影響元空間大小,因?yàn)镸etaspace是一個(gè)堆外數(shù)據(jù)區(qū)。為了限制Metaspace大小,我們使用其他調(diào)優(yōu)標(biāo)志:

-XX:MetaspaceSize和-XX:MaxMetaspaceSize設(shè)置最小和最大元空間大小
在Java 8之前,-XX:PermSize和-XX:MaxPermSize設(shè)置最小和最大PermGen大小

2.2. Threads(線程)

JVM中最耗費(fèi)內(nèi)存的數(shù)據(jù)區(qū)之一是堆棧,與每個(gè)線程同時(shí)創(chuàng)建。堆棧存儲(chǔ)局部變量和部分結(jié)果,在方法調(diào)用中起著重要作用。

默認(rèn)的線程堆棧大小取決于平臺(tái),但在大多數(shù)現(xiàn)代64位操作系統(tǒng)中,它大約為1 MB。此大小可通過(guò)-Xss調(diào)整標(biāo)志進(jìn)行配置。

與其他數(shù)據(jù)區(qū)域相比,當(dāng)對(duì)線程數(shù)沒(méi)有限制時(shí),分配給堆棧的總內(nèi)存實(shí)際上是無(wú)限制的。值得一提的是,JVM本身需要一些線程來(lái)執(zhí)行其內(nèi)部操作,如GC或即時(shí)編譯。

2.3. Code Cache(代碼緩存)

為了在不同平臺(tái)上運(yùn)行JVM字節(jié)碼,需要將其轉(zhuǎn)換為機(jī)器指令。執(zhí)行程序時(shí),JIT編譯器負(fù)責(zé)此編譯。

當(dāng)JVM將字節(jié)碼編譯為匯編指令時(shí),它會(huì)將這些指令存儲(chǔ)在稱為代碼緩存的特殊非堆數(shù)據(jù)區(qū)中??梢韵窆芾鞪VM中的其他數(shù)據(jù)區(qū)一樣管理代碼緩存。 -XX:InitialCodeCacheSize和-XX:ReservedCodeCacheSize調(diào)整標(biāo)志確定代碼緩存的初始值和可能最大值。

2.4. Garbage Collection(垃圾回收)

JVM附帶了一些GC算法,每個(gè)算法適用于不同的用例。所有這些GC算法都有一個(gè)共同的特點(diǎn):他們需要使用一些堆外數(shù)據(jù)結(jié)構(gòu)來(lái)執(zhí)行他們的任務(wù)。這些內(nèi)部數(shù)據(jù)結(jié)構(gòu)消耗更多本機(jī)內(nèi)存。

2.5. Symbols(符號(hào))

讓我們從 Strings 開(kāi)始,這是應(yīng)用程序和庫(kù)代碼中最常用的數(shù)據(jù)類型之一。由于它們無(wú)處不在,它們通常占據(jù)堆的很大一部分。如果大量的這些字符串包含相同的內(nèi)容,那么堆的很大一部分將被浪費(fèi)。

為了節(jié)省一些堆空間,我們可以存儲(chǔ)每個(gè) String 的一個(gè)版本,并讓其他版本引用存儲(chǔ)的版本。此過(guò)程稱為 String Interning 。由于JVM只能內(nèi)部編譯時(shí)間字符串常量,我們可以手動(dòng)調(diào)用字符串的intern方法來(lái)獲取內(nèi)部編譯字符串。

JVM將實(shí)際存儲(chǔ)的字符串存儲(chǔ)在本機(jī)特殊固定大小并稱為字符串表的哈希表中,也稱為字符串池。我們可以通過(guò)-XX:StringTableSize調(diào)整標(biāo)志配置表大小(即桶的數(shù)量)。

除了字符串表之外,還有另一個(gè)稱為運(yùn)行時(shí)常量池的本機(jī)數(shù)據(jù)區(qū)域。 JVM使用此池來(lái)存儲(chǔ)常量,如編譯時(shí)數(shù)字文字或必須在運(yùn)行時(shí)解析的方法和字段引用。

2.6. Native Byte Buffers(本地字節(jié)緩沖區(qū))

JVM通常有大量分配本機(jī)內(nèi)存的嫌疑,但有時(shí)開(kāi)發(fā)人員也可以直接分配本機(jī)內(nèi)存。最常見(jiàn)的方法是被JNI調(diào)用的malloc和NIO中可直接調(diào)用的ByteBuffers。

2.7. Additional Tuning Flags(額外的調(diào)整標(biāo)志)

在本節(jié)中,我們針對(duì)不同的優(yōu)化方案使用了少量JVM調(diào)優(yōu)標(biāo)志。使用以下提示,我們幾乎可以找到與特定概念相關(guān)的所有調(diào)優(yōu)標(biāo)志:

$ java -XX:+PrintFlagsFinal -version | grep <concept>

 

PrintFlagsFinal打印JVM中的所有-XX選項(xiàng)。例如,要查找所有與Metaspace相關(guān)的標(biāo)志:

$ java -XX:+PrintFlagsFinal -version | grep Metaspace
// truncated
uintx MaxMetaspaceSize = 18446744073709547520 {product}
uintx MetaspaceSize = 21807104 {pd product}
// truncated

 

3. 本機(jī)內(nèi)存跟蹤 (NMT)

現(xiàn)在我們已經(jīng)了解了JVM中本機(jī)內(nèi)存分配的常見(jiàn)來(lái)源,現(xiàn)在是時(shí)候找出如何監(jiān)視它們了。首先,我們應(yīng)該使用另一個(gè)JVM調(diào)優(yōu)標(biāo)志啟用本機(jī)內(nèi)存跟蹤:-XX:NativeMemoryTracking = off | sumary | detail。默認(rèn)情況下,NMT處于關(guān)閉狀態(tài),但我們可以使其查看其觀察的摘要或詳細(xì)視圖。

假設(shè)我們想要跟蹤典型Spring Boot應(yīng)用程序的本機(jī)分配:

$ java -XX:NativeMemoryTracking=summary -Xms300m -Xmx300m -XX:+UseG1GC -jar app.jar

 

在這里,我們?cè)诜峙?00 MB堆空間的同時(shí)啟用NMT,G1作為我們的GC算法。

3.1. 實(shí)例快照
啟用NMT后,我們可以使用jcmd命令隨時(shí)獲取本機(jī)內(nèi)存信息:

$ jcmd <pid> VM.native_memory

 

為了找到JVM應(yīng)用程序的PID,我們可以使用jps命令:

$ jps -l 
7858 app.jar // This is our app
7899 sun.tools.jps.Jps

 

現(xiàn)在,如果我們將jcmd與適當(dāng)?shù)膒id一起使用,VM.native_memory會(huì)使JVM打印出有關(guān)本機(jī)分配的信息:

$ jcmd 7858 VM.native_memory

讓我們逐節(jié)分析NMT輸出。

3.2. 總分配

NMT報(bào)告全部保留和提交的內(nèi)存如下:

Native Memory Tracking:
Total: reserved=1731124KB, committed=448152KB
保留內(nèi)存表示我們的應(yīng)用程序可能使用的內(nèi)存總量。相反,提交的內(nèi)存表示我們的應(yīng)用程序現(xiàn)在使用的內(nèi)存量。

盡管分配了300MB的堆,我們的應(yīng)用程序的總預(yù)留內(nèi)存幾乎是1.7 GB,遠(yuǎn)遠(yuǎn)超過(guò)它。類似地,提交的內(nèi)存大約為440 MB,這再次遠(yuǎn)遠(yuǎn)超過(guò)300 MB。

在整體了解之后,NMT報(bào)告每個(gè)分配源的內(nèi)存分配。所以,讓我們深入探討每個(gè)來(lái)源。

3.3. Heap(堆)

NMT按我們的預(yù)期報(bào)告堆分配:

Java Heap (reserved=307200KB, committed=307200KB)

(mmap: reserved=307200KB, committed=307200KB)

300 MB的保留和已提交內(nèi)存,與我們的堆大小設(shè)置相匹配。

3.4. Metaspace(元空間)

這是NMT關(guān)于加載類的元數(shù)據(jù)的報(bào)告:

Class (reserved=1091407KB, committed=45815KB)
(classes #6566)
(malloc=10063KB #8519) 
(mmap: reserved=1081344KB, committed=35752KB)

 

幾乎保留了1 GB,45 MB保留加載6566個(gè)類。

3.5. Thread(線程)
這是關(guān)于線程分配的NMT報(bào)告:

Thread (reserved=37018KB, committed=37018KB)
(thread #37)
(stack: reserved=36864KB, committed=36864KB)
(malloc=112KB #190) 
(arena=42KB #72)

 

總共有36 MB的內(nèi)存被分配給37個(gè)線程的堆棧 - 每個(gè)堆棧大約1 MB。 JVM在創(chuàng)建時(shí)將內(nèi)存分配給線程,因此保留和提交的分配是相等的。

3.6. Code Cache(代碼緩沖區(qū))
讓我們看看NMT對(duì)JIT生成和緩存的匯編指令的報(bào)告:

Code (reserved=251549KB, committed=14169KB)
(malloc=1949KB #3424) 
(mmap: reserved=249600KB, committed=12220KB)

目前,正在緩存大約13 MB的代碼,這個(gè)數(shù)量可能會(huì)達(dá)到245 MB。

3.7. GC
以下是有關(guān)G1 GC內(nèi)存使用情況的NMT報(bào)告:

GC (reserved=61771KB, committed=61771KB)
(malloc=17603KB #4501) 
(mmap: reserved=44168KB, committed=44168KB)

我們可以看到,保留和已提交都接近60 MB,致力于幫助G1。

讓我們來(lái)看看更簡(jiǎn)單的GC的內(nèi)存使用情況,比如Serial GC:

$ java -XX:NativeMemoryTracking=summary -Xms300m -Xmx300m -XX:+UseSerialGC -jar app.jar
Serial GC 幾乎使用不到1 MB:

GC (reserved=1034KB, committed=1034KB)
(malloc=26KB #158) 
(mmap: reserved=1008KB, committed=1008KB)

顯然,我們不能僅僅因?yàn)槠鋬?nèi)存使用而選擇GC算法,因?yàn)榇蠫C的暫?;厥毡举|(zhì)可能會(huì)導(dǎo)致性能下降。但是,還有幾個(gè)GC可供選擇,它們各自平衡內(nèi)存和性能。

3.8. Symbol(符號(hào))

以下是有關(guān)符號(hào)分配的NMT報(bào)告,例如字符串表和常量池:

Symbol (reserved=10148KB, committed=10148KB)
(malloc=7295KB #66194) 
(arena=2853KB #1)

將近10 MB分配給符號(hào)。

3.9. 隨著時(shí)間的推移的NMT

NMT允許我們跟蹤內(nèi)存分配如何隨時(shí)間變化。首先,我們應(yīng)該將應(yīng)用程序的當(dāng)前狀態(tài)標(biāo)記為基線:

$ jcmd <pid> VM.native_memory baseline

Baseline succeeded

然后,過(guò)了一會(huì)兒,我們可以將當(dāng)前的內(nèi)存使用情況與該基線(baseline)進(jìn)行比較:

$ jcmd <pid> VM.native_memory summary.diff

NMT使用+和 - 符號(hào)將告訴我們?cè)诖似陂g內(nèi)存使用情況如何變化:

Total: reserved=1771487KB +3373KB, committed=491491KB +6873KB
- Java Heap (reserved=307200KB, committed=307200KB)
(mmap: reserved=307200KB, committed=307200KB)

- Class (reserved=1084300KB +2103KB, committed=39356KB +2871KB)
// Truncated

保留和提交的總內(nèi)存分別增加了3 MB和6 MB??梢院苋菀椎匕l(fā)現(xiàn)內(nèi)存分配的其他波動(dòng)。

3.10. 詳細(xì)的NMT

NMT可以提供非常詳細(xì)的有關(guān)整個(gè)存儲(chǔ)空間映射的信息。要啟用此詳細(xì)報(bào)告,我們應(yīng)使用 -XX:NativeMemoryTracking =detail 信息調(diào)整標(biāo)志。

4. 結(jié)束語(yǔ)

在本文中,我們列舉了JVM中本機(jī)內(nèi)存分配的不同使用者。然后,我們學(xué)習(xí)了如何檢查正在運(yùn)行的應(yīng)用程序以監(jiān)視其本機(jī)分配。借助以上這些,我們可以更有效地調(diào)整應(yīng)用程序以及運(yùn)行時(shí)環(huán)境的大小。

相關(guān)文章

  • 基于SSM+Shiro+Bootstrap實(shí)現(xiàn)用戶權(quán)限管理系統(tǒng)

    基于SSM+Shiro+Bootstrap實(shí)現(xiàn)用戶權(quán)限管理系統(tǒng)

    這篇文章主要介紹了基于SSM+Shiro實(shí)現(xiàn)一個(gè)用戶權(quán)限管理系統(tǒng),每位用戶只可訪問(wèn)指定的頁(yè)面,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)或工作有一定幫助,快跟隨小編一起學(xué)習(xí)吧
    2021-12-12
  • Java設(shè)計(jì)模式之觀察者模式

    Java設(shè)計(jì)模式之觀察者模式

    這篇文章主要為大家介紹了Java觀察者模式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2021-12-12
  • SpringBoot中熔斷器的原理和使用詳解

    SpringBoot中熔斷器的原理和使用詳解

    這篇文章主要介紹了SpringBoot中熔斷器的原理和使用詳解,熔斷器是一種用于處理分布式系統(tǒng)中故障的設(shè)計(jì)模式,它可以防止出現(xiàn)故障的服務(wù)對(duì)整個(gè)系統(tǒng)造成連鎖反應(yīng),需要的朋友可以參考下
    2023-07-07
  • JAVA通過(guò)XPath解析XML性能比較詳解

    JAVA通過(guò)XPath解析XML性能比較詳解

    本篇文章主要介紹了JAVA通過(guò)XPath解析XML性能比較詳解,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-02-02
  • Java線程池的拒絕策略實(shí)現(xiàn)詳解

    Java線程池的拒絕策略實(shí)現(xiàn)詳解

    這篇文章主要介紹了Java線程池的拒絕策略實(shí)現(xiàn)詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-09-09
  • Java實(shí)現(xiàn)給微信群中定時(shí)推送消息

    Java實(shí)現(xiàn)給微信群中定時(shí)推送消息

    這篇文章主要為大家詳細(xì)介紹了Java如何實(shí)現(xiàn)給微信群中定時(shí)推送消息的功能,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的可以了解一下
    2022-12-12
  • 詳解mysql插入數(shù)據(jù)后返回自增ID的七種方法

    詳解mysql插入數(shù)據(jù)后返回自增ID的七種方法

    這篇文章主要介紹了詳解mysql插入數(shù)據(jù)后返回自增ID的七種方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • Java Map.getOrDefault方法詳解

    Java Map.getOrDefault方法詳解

    Map.getOrDefault(Object key, V defaultValue)是Java中Map接口的一個(gè)方法,用于獲取指定鍵對(duì)應(yīng)的值,如果鍵不存在,則返回一個(gè)默認(rèn)值,這篇文章主要介紹了Java Map.getOrDefault方法詳解,需要的朋友可以參考下
    2024-01-01
  • springboot中@RestController注解實(shí)現(xiàn)

    springboot中@RestController注解實(shí)現(xiàn)

    在JavaWeb開(kāi)發(fā)中,Spring框架及其組件SpringMVC因高效和強(qiáng)大功能而廣受歡迎,@RestController注解是SpringMVC中的重要組成部分,下面就來(lái)介紹一下,感興趣的可以了解一下
    2024-09-09
  • java使用Filter實(shí)現(xiàn)自動(dòng)登錄的方法

    java使用Filter實(shí)現(xiàn)自動(dòng)登錄的方法

    這篇文章主要為大家詳細(xì)介紹了java使用Filter實(shí)現(xiàn)自動(dòng)登錄的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-04-04

最新評(píng)論

柳江县| 洛宁县| 道真| 游戏| 井陉县| 沁源县| 清丰县| 安义县| 仁寿县| 长阳| 泰来县| 凭祥市| 百色市| 瑞昌市| 丰城市| 永安市| 云林县| 武冈市| 娱乐| 康乐县| 铅山县| 黎川县| 全椒县| 南通市| 西贡区| 玛多县| 历史| 台湾省| 大悟县| 工布江达县| 常德市| 鹤壁市| 新宾| 博客| 全椒县| 南宫市| 新兴县| 藁城市| 申扎县| 津市市| 永胜县|