色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

介紹一下使用NMT協(xié)助排查內(nèi)存問(wèn)題的案例

openEuler ? 來(lái)源:畢昇編譯 ? 作者:竇義望 ? 2022-11-16 11:33 ? 次閱讀

從前面幾篇文章,我們了解了 NMT 的基礎(chǔ)知識(shí)以及 NMT 追蹤區(qū)域分析的相關(guān)內(nèi)容,本篇文章將為大家介紹一下使用 NMT 協(xié)助排查內(nèi)存問(wèn)題的案例。

6.使用 NMT 協(xié)助排查內(nèi)存問(wèn)題案例

我們?cè)诟闱宄?NMT 追蹤的 JVM 各部分的內(nèi)存分配之后,就可以比較輕松的協(xié)助排查定位內(nèi)存問(wèn)題或者調(diào)整合適的參數(shù)

可以在 JVM 運(yùn)行時(shí)使用 jcmd VM.native_memory baseline 創(chuàng)建基線,經(jīng)過(guò)一段時(shí)間的運(yùn)行后再使用 jcmd VM.native_memory summary.diff/detail.diff 命令,就可以很直觀地觀察出這段時(shí)間 JVM 進(jìn)程使用的內(nèi)存一共增長(zhǎng)了多少,各部分使用的內(nèi)存分別增長(zhǎng)了多少,可以很方便的將問(wèn)題定位到某一具體的區(qū)域。

比如我們看到 MetaSpace 的內(nèi)存增長(zhǎng)異常,可以結(jié)合 MAT 等工具查看是否類加載器數(shù)量異常、是否類重復(fù)加載、reflect 的 inflation 參數(shù)設(shè)置是否合理;如果 Symbol 內(nèi)存增長(zhǎng)異常,可以查看項(xiàng)目 String.intern 是否使用正常;如果 Thread 使用內(nèi)存過(guò)多,考慮是否可以適當(dāng)調(diào)整線程堆棧大小等等。

案例一:虛高的 VIRT 內(nèi)存

我們還記得前文(NMT 內(nèi)存 & OS 內(nèi)存概念差異性章節(jié))中使用 top 命令查看啟動(dòng)的 JVM 進(jìn)程,仔細(xì)觀察會(huì)發(fā)現(xiàn)一個(gè)比較虛高的 VIRT 內(nèi)存(10.7g),我們使用 NMT 追蹤的 Total: reserved 才 2813709KB(2.7g),這多出來(lái)的這么多虛擬內(nèi)存是從何而來(lái)呢?

top

PIDUSERPRNIVIRTRESSHRS%CPU%MEMTIME+COMMAND
27420douyiwa+20010.7g69756017596S100.00.30:18.79java

NativeMemoryTracking:

Total:reserved=2813077KB,committed=1496981KB

使用pmap -X 觀察內(nèi)存情況:

27420:java-Xmx1G-Xms1G-XX:+UseG1GC-XX:MaxMetaspaceSize=256M-XX:MaxDirectMemorySize=256M-XX:ReservedCodeCacheSize=256M-XX:NativeMemoryTracking=detail-jarnmtTest.jar
AddressPermOffsetDeviceInodeSizeRssPssReferencedAnonymousLazyFreeShmemPmdMappedShared_HugetlbPrivate_HugetlbSwapSwapPssLockedMapping
c0000000rw-p0000000000:00010490886372366372366372366372360000000
100080000---p0000000000:000104806400000000000
aaaaea835000r-xp00000000fd:0245613083444400000000java
aaaaea854000r--p0000f000fd:0245613083444440000000java
aaaaea855000rw-p00010000fd:0245613083444440000000java
aaab071af000rw-p0000000000:0003041081081081080000000[heap]
fffd60000000rw-p0000000000:00013244440000000
fffd60021000---p0000000000:0006540400000000000
fffd68000000rw-p0000000000:00013288880000000
fffd68021000---p0000000000:0006540400000000000
fffd6c000000rw-p0000000000:00013244440000000
fffd6c021000---p0000000000:0006540400000000000
fffd70000000rw-p0000000000:000132404040400000000
fffd70021000---p0000000000:0006540400000
......

可以發(fā)現(xiàn)多了很多 65404 KB 的內(nèi)存塊(大約 120 個(gè)),使用 /proc//smaps 觀察內(nèi)存地址:

......
fffd60021000-fffd64000000---p0000000000:000
Size:65404kB
KernelPageSize:4kB
MMUPageSize:4kB
Rss:0kB
Pss:0kB
Shared_Clean:0kB
Shared_Dirty:0kB
Private_Clean:0kB
Private_Dirty:0kB
Referenced:0kB
Anonymous:0kB
LazyFree:0kB
AnonHugePages:0kB
ShmemPmdMapped:0kB
Shared_Hugetlb:0kB
Private_Hugetlb:0kB
Swap:0kB
SwapPss:0kB
Locked:0kB
VmFlags:mrmwmenr
......

對(duì)照 NMT 的情況,我們發(fā)現(xiàn)如 fffd60021000-fffd64000000 這種 65404 KB 的內(nèi)存是并沒(méi)有被 NMT 追蹤到的。這是因?yàn)樵?JVM 進(jìn)程中,除了 JVM 進(jìn)程自己 mmap 的內(nèi)存(如 Java Heap,和用戶進(jìn)程空間的 Heap 并不是一個(gè)概念)外,JVM 還直接使用了類庫(kù)的函數(shù)來(lái)分配一些數(shù)據(jù),如使用 Glibc 的 malloc/free (也是通過(guò) brk/mmap 的方式):

6456547a-64fa-11ed-8abf-dac502259ad0.png

既然 JVM 使用了 Glibc 的 malloc/free,就不得不提及 malloc 的機(jī)制,早期版本的 malloc 只有一個(gè) arena(分配區(qū)),每次分配時(shí)都要對(duì)分配區(qū)加鎖,分配完成之后再釋放,這就導(dǎo)致了多線程的情況下競(jìng)爭(zhēng)比較激烈。

所以 malloc 改動(dòng)了其分配機(jī)制,甚至有了 arena per-thread 的模式,即如果在一個(gè)線程中首次調(diào)用 malloc,則創(chuàng)建一個(gè)新的 arena,而不是去查看前面的鎖是否會(huì)發(fā)生競(jìng)爭(zhēng),對(duì)于一定數(shù)量的線程可以避免競(jìng)爭(zhēng)在自己的 arena 上工作。

arena 的數(shù)量限制在 32 位系統(tǒng)上是 2 * CPU 核心數(shù),64 位系統(tǒng)上是 8 * CPU 核心數(shù),當(dāng)然我們也可以使用 MALLOC_ARENA_MAX (Linux 環(huán)境變量,詳情可以查看 mallopt(3)[1])來(lái)控制。

查看發(fā)現(xiàn)運(yùn)行 JVM 進(jìn)程的環(huán)境 CPU 信息(物理 CPU 核數(shù)):Core(s) per socket: 64 。

我們給當(dāng)前環(huán)境設(shè)置 MALLOC_ARENA_MAX=2,重啟 JVM 進(jìn)程,查看使用情況:

top

PIDUSERPRNIVIRTRESSHRS%CPU%MEMTIME+COMMAND
36319douyiwa+200310834069087217828S100.00.30:07.61java

虛高的 VIRT 內(nèi)存已經(jīng)降下來(lái)了,繼續(xù)查看 pmap/smaps 會(huì)發(fā)現(xiàn)眾多的 65404 KB 的內(nèi)存空間也消失了(120 * 65404 KB = 7848480 KB 正好對(duì)應(yīng)了 10.7g - 3108340 KB 的內(nèi)存,即 VIRT 降低的內(nèi)存)。

為什么我們的 JVM 進(jìn)程會(huì)使用如此多的 arena 呢?因?yàn)槲覀冊(cè)趩?dòng) JVM 進(jìn)程的時(shí)候,并沒(méi)有手動(dòng)去設(shè)置一些進(jìn)程的數(shù)目,如:CICompilerCount(編譯線程數(shù))、ConcGCThreads/ParallelGCThreads(并發(fā) GC 線程數(shù))、G1ConcRefinementThreads(G1 Refine 線程數(shù))等等。

這些參數(shù)大多數(shù)根據(jù)當(dāng)前機(jī)器的 CPU 核數(shù)去計(jì)算默認(rèn)值,使用 jinfo -flags 查看機(jī)器參數(shù)發(fā)現(xiàn):

-XX:CICompilerCount=18
-XX:ConcGCThreads=11
-XX:G1ConcRefinementThreads=43

這些線程數(shù)目都是比較大的,我們也可以不修改 MALLOC_ARENA_MAX 的數(shù)量,而通過(guò)參數(shù)減小線程的數(shù)量來(lái)減少 arena 的數(shù)量。

Glibc 的 malloc 有時(shí)會(huì)出現(xiàn)碎片問(wèn)題,可以使用 jemalloc/tcmalloc 等替代 Glibc。

案例二:堆外內(nèi)存的排查

有時(shí)候我們會(huì)發(fā)現(xiàn),Java 堆、MetaSpace 等區(qū)域是比較正常的,但是 JVM 進(jìn)程整體的內(nèi)存卻在不停的增長(zhǎng),此時(shí)我們就可以使用 NMT 的 baseline & diff 功能來(lái)觀察究竟是哪塊區(qū)域內(nèi)存一直增長(zhǎng)。

比如在一次案例中發(fā)現(xiàn):

NativeMemoryTracking:
Total:reserved=8149334KB+1535794KB,committed=6999194KB+1590490KB
......
-Internal(reserved=1723321KB+1472458KB,committed=1723321KB+1472458KB)
(malloc=1723289KB+1472458KB#109094+47573)
(mmap:reserved=32KB,committed=32KB)
......
[0x00007fceb806607a]Unsafe_AllocateMemory+0x17a
[0x00007fcea1d24e68]
(malloc=1485579KBtype=Internal+1455929KB#2511+2277)
......

我們可以確認(rèn)內(nèi)存 1590490KB 的增長(zhǎng),基本上都是由 Internal 的 Unsafe_AllocateMemory 所分配的,此時(shí)可以優(yōu)先考慮 NIO 中 ByteBuffer.allocateDirect / DirectByteBuffer / FileChannel.map 等使用方式是不是出現(xiàn)了泄漏,可以使用 MAT 查看 DirectByteBuffer 對(duì)象的數(shù)量是否異常,并可以使用 -XX:MaxDirectMemorySize 來(lái)限制 Direct 的大小。

設(shè)置 -XX:MaxDirectMemorySize 之后,進(jìn)程異常的內(nèi)存增長(zhǎng)停止,但是 GC 頻率變高,查看 GC 日志發(fā)現(xiàn):.887+0800: 238210.127: [Full GC (System.gc()) 1175M->255M(3878),0.8370418 secs]。

FullGC 的頻率大大增加,并且基本上都是由 System.gc() 顯式調(diào)用引起的(HotSpot中的System.gc()為 FulGC),查看 DirectByteBuffer 相關(guān)邏輯:

#DirectByteBuffer.java

DirectByteBuffer(intcap){//package-private
......
Bits.reserveMemory(size,cap);

longbase=0;
try{
base=unsafe.allocateMemory(size);
}catch(OutOfMemoryErrorx){
Bits.unreserveMemory(size,cap);
throwx;
}
unsafe.setMemory(base,size,(byte)0);
if(pa&&(base%ps!=0)){
//Rounduptopageboundary
address=base+ps-(base&(ps-1));
}else{
address=base;
}
cleaner=Cleaner.create(this,newDeallocator(base,size,cap));
att=null;
}

#Bits.java

staticvoidreserveMemory(longsize,intcap){
......
System.gc();
......
}

DirectByteBuffer 在 unsafe.allocateMemory(size) 之前會(huì)先去做一個(gè) Bits.reserveMemory(size, cap) 的操作,Bits.reserveMemory 會(huì)顯式的調(diào)用 System.gc() 來(lái)嘗試回收內(nèi)存,看到這里基本可以確認(rèn)為 DirectByteBuffer 的問(wèn)題,排查業(yè)務(wù)代碼,果然發(fā)現(xiàn)一處 ByteBufferStream 使用了 ByteBuffer.allocateDirect 的方式而流一直未關(guān)閉釋放內(nèi)存,修正后內(nèi)存增長(zhǎng)與 GC 頻率皆恢復(fù)正常。






審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • JVM
    JVM
    +關(guān)注

    關(guān)注

    0

    文章

    158

    瀏覽量

    12238
  • LINUX內(nèi)核
    +關(guān)注

    關(guān)注

    1

    文章

    316

    瀏覽量

    21672
  • NMT
    NMT
    +關(guān)注

    關(guān)注

    0

    文章

    7

    瀏覽量

    3647

原文標(biāo)題:Native Memory Tracking 詳解(4):使用 NMT 協(xié)助排查內(nèi)存問(wèn)題案例

文章出處:【微信號(hào):openEulercommunity,微信公眾號(hào):openEuler】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    詳細(xì)介紹一下PSS+Pnoise仿真

    PSS+Pnoise仿真是很多電路要用到的仿真,今天我們?cè)敿?xì)介紹一下這個(gè)仿真。
    的頭像 發(fā)表于 11-03 18:13 ?7893次閱讀
    詳細(xì)<b class='flag-5'>介紹</b><b class='flag-5'>一下</b>PSS+Pnoise仿真

    RTOS內(nèi)存管理問(wèn)題誰(shuí)來(lái)解答一下

    定義了個(gè)buff,通過(guò)pvPortMalloc函數(shù)給buff申請(qǐng)了內(nèi)存。但是如何去判斷我申請(qǐng)到的BUFF的內(nèi)存有沒(méi)有用完呢?看來(lái)一下介紹
    發(fā)表于 06-15 04:35

    請(qǐng)問(wèn)一下示波器可用于EMI排查嗎?

    請(qǐng)問(wèn)一下示波器可用于EMI排查嗎?
    發(fā)表于 04-30 06:48

    請(qǐng)問(wèn)一下示波器可用于電磁干擾排查嘛?

    工程師在排查EMI問(wèn)題所面臨的最常見(jiàn)的挑戰(zhàn)是什么?如何區(qū)分出無(wú)用的騷擾行為?請(qǐng)問(wèn)一下示波器可用于電磁干擾排查嘛?
    發(fā)表于 05-08 07:40

    分享內(nèi)存泄漏定位排查技巧

    的調(diào)試工具,下面分享內(nèi)存泄漏定位排查技巧。1.對(duì)malloc,free進(jìn)行封裝首先,我們對(duì)malloc,f
    發(fā)表于 12-17 08:13

    Native Memory Tracking 詳解(4):使用 NMT 協(xié)助排查內(nèi)存問(wèn)題案例

    從前面幾篇文章,我們了解了 NMT 的基礎(chǔ)知識(shí)以及 NMT 追蹤區(qū)域分析的相關(guān)內(nèi)容,本篇文章將為大家介紹一下使用 NMT
    發(fā)表于 11-24 14:19

    簡(jiǎn)要介紹一下Python-UNO的使用方法

    OpenOffice是個(gè)免費(fèi)的、開(kāi)源的辦公套裝,集成了允許開(kāi)發(fā)者用不同語(yǔ)言進(jìn)行開(kāi)發(fā)的API。Python-UNO讓你可以在Python環(huán)境使用OpenOffice。本文簡(jiǎn)要介紹一下
    的頭像 發(fā)表于 01-04 14:54 ?8618次閱讀
    簡(jiǎn)要<b class='flag-5'>介紹</b><b class='flag-5'>一下</b>Python-UNO的使用方法

    電磁爐加熱一下就停一下什么原因及解決辦法

    電磁爐有時(shí)會(huì)出現(xiàn)加熱故障,現(xiàn)象是熱一下一下在熱一下又停一下,基本隔
    發(fā)表于 03-18 09:02 ?27.5w次閱讀

    電磁爐加熱一下就停一下什么原因

    電磁爐加熱一下就停一下什么原因。
    的頭像 發(fā)表于 06-04 10:01 ?3.8w次閱讀

    如何使用NMT和pmap來(lái)解決JVM的資源泄漏問(wèn)題

    編者按:筆者使用 JDK 自帶的內(nèi)存跟蹤工具 NMT 和 Linux 自帶的 pmap 解決了個(gè)非常典型的資源泄漏問(wèn)題。這個(gè)資源泄漏是由于 Java 程序員不正確地使用 Java API 導(dǎo)致
    的頭像 發(fā)表于 09-24 16:00 ?3512次閱讀
    如何使用<b class='flag-5'>NMT</b>和pmap來(lái)解決JVM的資源泄漏問(wèn)題

    介紹NMT追蹤區(qū)域的部分內(nèi)存類型

    除去這上面的部分選項(xiàng),我們發(fā)現(xiàn) NMT 中還有個(gè) unknown 選項(xiàng),這主要是在執(zhí)行 jcmd 命令時(shí),內(nèi)存類別還無(wú)法確定或虛擬類型信息還沒(méi)有到達(dá)時(shí)的
    的頭像 發(fā)表于 10-21 09:26 ?1217次閱讀

    介紹一下高低溫試驗(yàn)箱的校驗(yàn)項(xiàng)目與方法

    介紹一下高低溫試驗(yàn)箱的校驗(yàn)項(xiàng)目與方法
    的頭像 發(fā)表于 06-12 09:49 ?477次閱讀
    <b class='flag-5'>介紹</b><b class='flag-5'>一下</b>高低溫試驗(yàn)箱的校驗(yàn)項(xiàng)目與方法

    次Rust內(nèi)存泄漏排查之旅

    在某次持續(xù)壓測(cè)過(guò)程中,我們發(fā)現(xiàn) GreptimeDB 的 Frontend 節(jié)點(diǎn)內(nèi)存即使在請(qǐng)求量平穩(wěn)的階段也在持續(xù)上漲,直至被 OOM kill。我們判斷 Frontend 應(yīng)該是有內(nèi)存泄漏了,于是開(kāi)啟了排查
    的頭像 發(fā)表于 07-02 11:52 ?683次閱讀
    記<b class='flag-5'>一</b>次Rust<b class='flag-5'>內(nèi)存</b>泄漏<b class='flag-5'>排查</b>之旅

    glibc導(dǎo)致的堆外內(nèi)存泄露的排查過(guò)程

    本文記錄次glibc導(dǎo)致的堆外內(nèi)存泄露的排查過(guò)程。
    的頭像 發(fā)表于 09-01 09:43 ?727次閱讀
    glibc導(dǎo)致的堆外<b class='flag-5'>內(nèi)存</b>泄露的<b class='flag-5'>排查</b>過(guò)程

    java內(nèi)存溢出排查方法

    過(guò)程中常見(jiàn)的問(wèn)題之,可能導(dǎo)致應(yīng)用程序崩潰、性能下降甚至系統(tǒng)崩潰。在本文中,將詳細(xì)介紹如何排查和解決Java內(nèi)存溢出問(wèn)題。 、什么是Jav
    的頭像 發(fā)表于 11-23 14:46 ?3258次閱讀
    主站蜘蛛池模板: 综合亚洲桃色第一影院| 国产在线观看www| 成人性生交大片免费看中文| 俄罗斯兽交XXXXX在线| 国产一区二区高清| 老师系列高H文| 色狐直播免费观看| 亚洲午夜无码久久久久蜜臀av| 999视频在线观看| 国产激情一级毛片久久久| 久久久久久亚洲精品影院| 日本亚洲中文字幕无码区| 亚洲视频 在线观看| yellow视频免费观看高清在线| 国产在线自天天人人| 欧美xxxxb| 亚洲VA天堂VA欧美VA在线| 97无码欧美熟妇人妻蜜| 国产精品成人影院在线观看| 久久伊人免费| 天天射天天干天天插| 2012中文字幕在线动漫电影| 国产精品女上位在线观看| 蜜臀AV999无码精品国产| 亚洲spank男男实践网站| jizz日本美女| 精品国产90后在线观看| 日韩经典欧美一区二区三区| 一个色综合久久| 国产99精品在线观看| 美女打开双腿扒开屁股男生| 亚洲 色 欧美 爱 视频 日韩| av影音先锋影院男人站| 灰原哀被啪漫画禁漫| 色愁愁久久久| 970女主播电台歌曲| 好男人免费观看在线高清WWW| 日韩欧美精品有码在线播放 | 毛茸茸womansex| 亚洲国产成人精品不卡青青草原 | 一个吃奶两个添下面H|