第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

Java使用比堆大小更多的內(nèi)存(或正確的Docker內(nèi)存限制大?。?/h1>

Java使用比堆大小更多的內(nèi)存(或正確的Docker內(nèi)存限制大?。?/h1>
繁花不似錦 2019-08-15 15:29:40
Java使用比堆大小更多的內(nèi)存(或正確的Docker內(nèi)存限制大?。?duì)于我的應(yīng)用程序,Java進(jìn)程使用的內(nèi)存遠(yuǎn)遠(yuǎn)超過堆大小。容器正在運(yùn)行的系統(tǒng)開始出現(xiàn)內(nèi)存問題,因?yàn)槿萜髡加玫膬?nèi)存比堆大小多得多。堆大小設(shè)置為128 MB(-Xmx128m -Xms128m),而容器最多占用1 GB內(nèi)存。在正常情況下,它需要500MB。如果docker容器具有以下限制(例如mem_limit=mem_limit=400MB),則該進(jìn)程被OS的內(nèi)存不足殺死所殺死。你能解釋為什么Java進(jìn)程使用比堆更多的內(nèi)存嗎?如何正確調(diào)整Docker內(nèi)存限制?有沒有辦法減少Java進(jìn)程的堆外內(nèi)存占用?我使用JVM中的本機(jī)內(nèi)存跟蹤命令收集有關(guān)該問題的一些詳細(xì)信息。從主機(jī)系統(tǒng),我獲得容器使用的內(nèi)存。$ docker stats --no-stream 9afcb62a26c8CONTAINER ID        NAME                                                                                        CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS9afcb62a26c8        xx-xxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.0acbb46bb6fe3ae1b1c99aff3a6073bb7b7ecf85   0.93%               461MiB / 9.744GiB   4.62%               286MB / 7.92MB      157MB / 2.66GB      57從容器內(nèi)部,我獲得進(jìn)程使用的內(nèi)存。$ ps -p 71 -o pcpu,rss,size,vsize%CPU   RSS  SIZE    VSZ11.2 486040 580860 3814600$ jcmd 71 VM.native_memory71:Native Memory Tracking:Total: reserved=1631932KB, committed=367400KB-                 Java Heap (reserved=131072KB, committed=131072KB)                            (mmap: reserved=131072KB, committed=131072KB) -                     Class (reserved=1120142KB, committed=79830KB)                            (classes #15267)                            (  instance classes #14230, array classes #1037)                            (malloc=1934KB #32977)                             (mmap: reserved=1118208KB, committed=77896KB)                             (  Metadata:   )                            (    reserved=69632KB, committed=68272KB)                            (    used=66725KB)                            (    free=1547KB)                            (    waste=0KB =0.00%)                            (  Class space:)                            (    reserved=1048576KB, committed=9624KB)                            (    used=8939KB)                            (    free=685KB)                            (    waste=0KB =0.00%)
查看完整描述

4 回答

?
德瑪西亞99

TA貢獻(xiàn)1770條經(jīng)驗(yàn) 獲得超3個(gè)贊

Java進(jìn)程使用的虛擬內(nèi)存遠(yuǎn)遠(yuǎn)超出了Java堆。您知道,JVM包含許多子系統(tǒng):垃圾收集器,類加載,JIT編譯器等,所有這些子系統(tǒng)都需要一定量的RAM才能運(yùn)行。

JVM不是RAM的唯一消費(fèi)者。本機(jī)庫(kù)(包括標(biāo)準(zhǔn)Java類庫(kù))也可以分配本機(jī)內(nèi)存。而本機(jī)內(nèi)存跟蹤甚至無(wú)法看到這一點(diǎn)。Java應(yīng)用程序本身也可以通過直接ByteBuffers使用堆外內(nèi)存。

那么什么需要Java進(jìn)程中的內(nèi)存?

JVM部件(主要通過本機(jī)內(nèi)存跟蹤顯示)

  1. Java堆

    最明顯的部分。這是Java對(duì)象所在的位置。堆占用了-Xmx大量的內(nèi)存。

  2. 垃圾收集器

    GC結(jié)構(gòu)和算法需要額外的內(nèi)存用于堆管理。這些結(jié)構(gòu)是Mark Bitmap,Mark Stack(用于遍歷對(duì)象圖),Remembered Sets(用于記錄區(qū)域間引用)等。其中一些是直接可調(diào)的,例如-XX:MarkStackSizeMax,其他一些依賴于堆布局,例如,較大的是G1區(qū)域(-XX:G1HeapRegionSize),較小的是記憶集。

    GC內(nèi)存開銷因GC算法而異。-XX:+UseSerialGC并且-XX:+UseShenandoahGC開銷最小。G1或CMS可以輕松使用總堆大小的10%左右。

  3. 代碼緩存

    包含動(dòng)態(tài)生成的代碼:JIT編譯的方法,解釋器和運(yùn)行時(shí)存根。它的大小受限于-XX:ReservedCodeCacheSize(默認(rèn)為240M)。關(guān)閉-XX:-TieredCompilation以減少編譯代碼的數(shù)量,從而減少代碼緩存的使用。

  4. 編譯器

    JIT編譯器本身也需要內(nèi)存來完成它的工作。通過關(guān)閉分層編譯或減少編譯器線程的數(shù)量,可以再次減少這種情況:-XX:CICompilerCount。

  5. 類加載

    類元數(shù)據(jù)(方法字節(jié)碼,符號(hào),常量池,注釋等)存儲(chǔ)在稱為Metaspace的堆外區(qū)域中。加載的類越多 - 使用的元空間就越多??偸褂昧靠梢允芟?code>-XX:MaxMetaspaceSize(默認(rèn)為無(wú)限制)和-XX:CompressedClassSpaceSize(默認(rèn)為1G)。

  6. 符號(hào)表

    JVM的兩個(gè)主要哈希表:Symbol表包含名稱,簽名,標(biāo)識(shí)符等,String表包含對(duì)實(shí)習(xí)字符串的引用。如果本機(jī)內(nèi)存跟蹤指示String表占用大量?jī)?nèi)存,則可能意味著應(yīng)用程序過度調(diào)用String.intern。

  7. 主題

    線程堆棧也負(fù)責(zé)占用RAM。堆棧大小由-Xss。每個(gè)線程的默認(rèn)值是1M,但幸運(yùn)的是事情并沒有那么糟糕。操作系統(tǒng)懶惰地分配內(nèi)存頁(yè)面,即在第一次使用時(shí),因此實(shí)際內(nèi)存使用量將低得多(通常每個(gè)線程堆棧80-200 KB)。我編寫了一個(gè)腳本來估計(jì)RSS有多少屬于Java線程堆棧。

    還有其他JVM部件可以分配本機(jī)內(nèi)存,但它們通常不會(huì)在總內(nèi)存消耗中發(fā)揮重要作用。

直接緩沖

應(yīng)用程序可以通過調(diào)用顯式請(qǐng)求堆外內(nèi)存ByteBuffer.allocateDirect。默認(rèn)的堆外限制等于-Xmx,但可以用它覆蓋-XX:MaxDirectMemorySize。Direct ByteBuffers包含在OtherNMT輸出部分(或InternalJDK 11之前)。

通過JMX可以看到使用的直接內(nèi)存量,例如在JConsole或Java Mission Control中:

除了直接的ByteBuffers,還可以有MappedByteBuffers- 映射到進(jìn)程虛擬內(nèi)存的文件。NMT不跟蹤它們,但MappedByteBuffers也可以占用物理內(nèi)存。而且沒有一種簡(jiǎn)單的方法來限制它們可以承受多少。您可以通過查看進(jìn)程內(nèi)存映射來查看實(shí)際使用情況:pmap -x <pid>

Address Kbytes    RSS    Dirty Mode Mapping ... 00007f2b3e557000 39592 32956 0 r--s- some-file-17405-Index.db 00007f2b40c01000 39600 33092 0 r--s- some-file-17404-Index.db                            ^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^

本地圖書館

加載的JNI代碼System.loadLibrary可以根據(jù)需要分配盡可能多的堆外內(nèi)存,而無(wú)需JVM端的控制。這也涉及標(biāo)準(zhǔn)的Java類庫(kù)。特別是,未封閉的Java資源可能成為本機(jī)內(nèi)存泄漏的來源。典型的例子是ZipInputStreamDirectoryStream。

JVMTI代理,特別是jdwp調(diào)試代理 - 也可能導(dǎo)致過多的內(nèi)存消耗。

此答案描述了如何使用async-profiler配置本機(jī)內(nèi)存分配。

分配器問題

進(jìn)程通常直接從OS(通過mmap系統(tǒng)調(diào)用)或使用malloc- 標(biāo)準(zhǔn)libc分配器請(qǐng)求本機(jī)內(nèi)存。反過來,malloc要求OS使用大塊內(nèi)存mmap,然后根據(jù)自己的分配算法管理這些塊。問題是 - 該算法可能導(dǎo)致碎片和過多的虛擬內(nèi)存使用。

jemalloc,替代分配器,通??雌饋肀瘸R?guī)libc更智能malloc,因此切換到jemalloc可能導(dǎo)致更小的空閑。

結(jié)論

沒有保證估計(jì)Java進(jìn)程的完整內(nèi)存使用量的方法,因?yàn)橛刑嘁蛩匦枰紤]。

Total memory = Heap + Code Cache + Metaspace + Symbol tables + Other JVM structures + Thread stacks + Direct buffers + Mapped files + Native Libraries + Malloc overhead + ...

可以通過JVM標(biāo)志縮小或限制某些內(nèi)存區(qū)域(如代碼緩存),但許多其他內(nèi)存區(qū)域完全不受JVM控制。

設(shè)置Docker限制的一種可能方法是在進(jìn)程的“正常”狀態(tài)下觀察實(shí)際內(nèi)存使用情況。有研究Java內(nèi)存消耗問題的工具和技術(shù):Native Memory Tracking,pmapjemalloc,async-profiler


查看完整回答
反對(duì) 回復(fù) 2019-08-15
?
斯蒂芬大帝

TA貢獻(xiàn)1827條經(jīng)驗(yàn) 獲得超8個(gè)贊

內(nèi)存的詳細(xì)用法由本機(jī)內(nèi)存跟蹤(NMT)詳細(xì)信息(主要是代碼元數(shù)據(jù)和垃圾收集器)提供。除此之外,Java編譯器和優(yōu)化器C1 / C2使用摘要中未報(bào)告的內(nèi)存。

使用JVM標(biāo)志可以減少內(nèi)存占用(但存在影響)。

必須通過測(cè)試應(yīng)用程序的預(yù)期負(fù)載來完成Docker容器大小調(diào)整。


每個(gè)組件的詳細(xì)信息

所述共享類空間可以在容器內(nèi)被禁用,因?yàn)轭惒粫?huì)被另一個(gè)JVM進(jìn)程共享??梢允褂靡韵聵?biāo)志。它將刪除共享類空間(17MB)。

-Xshare:off

所述垃圾收集器串行具有在更長(zhǎng)的暫停時(shí)間期間垃圾的成本最小的內(nèi)存占用收集處理(參照在一個(gè)畫面GC之間阿列克謝Shipil?v比較)??梢允褂靡韵聵?biāo)志啟用它。它可以節(jié)省使用的GC空間(48MB)。

-XX:+UseSerialGC

所述C2編譯器可以用下面的標(biāo)志被禁用,以減少用于決定是否優(yōu)化與否的方法分析數(shù)據(jù)。

-XX:+TieredCompilation -XX:TieredStopAtLevel=1

代碼空間減少了20MB。而且,JVM外部的內(nèi)存減少了80MB(NMT空間和RSS空間之間的差異)。優(yōu)化編譯器C2需要100MB。

C1和C2的編譯器可以用下面的標(biāo)志被禁用。

-Xint

JVM外部的內(nèi)存現(xiàn)在低于總提交空間。代碼空間減少了43MB。請(qǐng)注意,這會(huì)對(duì)應(yīng)用程序的性能產(chǎn)生重大影響。禁用C1和C2編譯器會(huì)減少170 MB的內(nèi)存使用量。

使用Graal VM編譯器(替換C2)可以減少內(nèi)存占用。它增加了20MB的代碼內(nèi)存空間,并從外部JVM內(nèi)存減少了60MB。

JVM的Java內(nèi)存管理文章提供了不同內(nèi)存空間的一些相關(guān)信息。Oracle在Native Memory Tracking文檔中提供了一些細(xì)節(jié)。有關(guān)高級(jí)編譯策略和禁用C2中的編譯級(jí)別的更多詳細(xì)信息將代碼高速緩存大小減少了5倍。有關(guān)為什么JVM報(bào)告的內(nèi)存比Linux進(jìn)程駐留集大小更多的一些細(xì)節(jié)?當(dāng)兩個(gè)編譯器都被禁用時(shí)。


查看完整回答
反對(duì) 回復(fù) 2019-08-15
  • 4 回答
  • 0 關(guān)注
  • 4165 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)