<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          內(nèi)存泄漏排查攻略之:Show me your Memory

          共 10098字,需瀏覽 21分鐘

           ·

          2021-06-15 21:17


          來(lái)源| cnblogs.com/yougewe/p/11334342.html


          java 語(yǔ)言有個(gè)神奇的地方,那就是你時(shí)不時(shí)會(huì)去關(guān)注下內(nèi)存。(當(dāng)然了,任何牛逼的同學(xué)都應(yīng)該關(guān)注內(nèi)存)

          今天我們就來(lái)這么個(gè)問(wèn)題現(xiàn)場(chǎng)吧:某應(yīng)用運(yùn)行了一段時(shí)間后,ecs監(jiān)控報(bào)警了,內(nèi)存比較高了,怎么辦?隨著時(shí)間的推移,發(fā)現(xiàn)內(nèi)存越來(lái)越高緩緩增長(zhǎng),怎么辦?

          凡事講究證據(jù),報(bào)警系統(tǒng)說(shuō)內(nèi)存緊張就緊張嗎,還得自己去驗(yàn)一下。

          如何確認(rèn)內(nèi)存問(wèn)題?這太重要了!其實(shí)只要給我看你內(nèi)存里所有東西(Show me your Memory),我豈有找不到問(wèn)題根源的道理?以下是幾種查看內(nèi)存問(wèn)題的方法供諸君參考:

          1:top 等查看系統(tǒng)內(nèi)存概況

          top:顯示所有進(jìn)程運(yùn)行情況,按M鍵按照內(nèi)存大小排序,立馬看到罪魁禍?zhǔn)住>唧w命令請(qǐng)參考網(wǎng)上資料。

          top簡(jiǎn)要使用方法如下:

          使用格式:top [-] [d] [p] [q] [c] [C] [S] [s] [n]參數(shù)說(shuō)明:d:指定每?jī)纱纹聊恍畔⑺⑿轮g的時(shí)間間隔。當(dāng)然用戶(hù)可以使用s交互命令來(lái)改變之。p:通過(guò)指定監(jiān)控進(jìn)程ID來(lái)僅僅監(jiān)控某個(gè)進(jìn)程的狀態(tài)。q:該選項(xiàng)將使top沒(méi)有任何延遲的進(jìn)行刷新。如果調(diào)用程序有超級(jí)用戶(hù)權(quán)限,那么top將以盡可能高的優(yōu)先級(jí)運(yùn)行。S:指定累計(jì)模式。s:使top命令在安全模式中運(yùn)行。這將去除交互命令所帶來(lái)的潛在危險(xiǎn)。i:使top不顯示任何閑置或者僵死進(jìn)程。c:顯示整個(gè)命令行而不只是顯示命令名。
          常用命令說(shuō)明:Ctrl+L:擦除并且重寫(xiě)屏幕K:終止一個(gè)進(jìn)程。系統(tǒng)將提示用戶(hù)輸入需要終止的進(jìn)程PID,以及需要發(fā)送給該進(jìn)程什么樣的信號(hào)。一般的終止進(jìn)程可以使用15信號(hào);如果不能正常結(jié)束那就使用信號(hào)9強(qiáng)制結(jié)束該進(jìn)程。默認(rèn)值是信號(hào)15。在安全模式中此命令被屏蔽。i:忽略閑置和僵死進(jìn)程。這是一個(gè)開(kāi)關(guān)式命令。q:退出程序r:重新安排一個(gè)進(jìn)程的優(yōu)先級(jí)別。系統(tǒng)提示用戶(hù)輸入需要改變的進(jìn)程PID以及需要設(shè)置的進(jìn)程優(yōu)先級(jí)值。輸入一個(gè)正值將使優(yōu)先級(jí)降低,反之則可以使該進(jìn)程擁有更高的優(yōu)先權(quán)。默認(rèn)值是10。S:切換到累計(jì)模式。s:改變兩次刷新之間的延遲時(shí)間。系統(tǒng)將提示用戶(hù)輸入新的時(shí)間,單位為s。如果有小數(shù),就換算成m s。輸入0值則系統(tǒng)將不斷刷新,默認(rèn)值是5 s。需要注意的是如果設(shè)置太小的時(shí)間,很可能會(huì)引起不斷刷新,從而根本來(lái)不及看清顯示的情況,而且系統(tǒng)負(fù)載也會(huì)大大增加。f或者F:從當(dāng)前顯示中添加或者刪除項(xiàng)目。o或者O:改變顯示項(xiàng)目的順序l:切換顯示平均負(fù)載和啟動(dòng)時(shí)間信息。m:切換顯示內(nèi)存信息。t:切換顯示進(jìn)程和CPU狀態(tài)信息。c:切換顯示命令名稱(chēng)和完整命令行。M:根據(jù)駐留內(nèi)存大小進(jìn)行排序。P:根據(jù)CPU使用百分比大小進(jìn)行排序。T:根據(jù)時(shí)間/累計(jì)時(shí)間進(jìn)行排序。W:將當(dāng)前設(shè)置寫(xiě)入~/.toprc文件中。

          另外在內(nèi)存查看方面,還可以使用 free用于快速直接查看內(nèi)存,還可以看到有多少是系統(tǒng)緩存;(系統(tǒng)緩存一般不被計(jì)入真正已使用內(nèi)存中)

          2. jmx 快速發(fā)現(xiàn)jvm中的內(nèi)存異常項(xiàng)

          jmx,如果開(kāi)啟了jmx,則我們可以直接通過(guò)jvisualvm查看內(nèi)存,線(xiàn)程監(jiān)控情況,還可以查看其他jmx指標(biāo);
          從這里你可以,看到內(nèi)存的變化趨勢(shì),垃圾回收,cpu變化趨勢(shì)等等,很多直觀的問(wèn)題完全可以在這一環(huán)節(jié)發(fā)現(xiàn)。
          另外,你可以通過(guò)采集cpu和采集內(nèi)存的方式,發(fā)現(xiàn)代碼中的瓶頸點(diǎn)。
          可以說(shuō),jmx是我們進(jìn)行代碼優(yōu)化或者參數(shù)調(diào)優(yōu)的絕對(duì)王者工具。

          性能問(wèn)題,可以適當(dāng)進(jìn)行CPU/內(nèi)存采樣,以快速發(fā)現(xiàn)瓶頸點(diǎn)!

          建議新增插件: 

          Btrace Workbench  用于遠(yuǎn)程調(diào)試,也許有用;

          BufferMonitor 用于查看堆外內(nèi)存情況,其實(shí)可能不準(zhǔn);

          Threads Inspector 用于快速查看各線(xiàn)程情況;

          VisualJVM-MBeans 用于查看 jmx 暴露出來(lái)的 指標(biāo)信息,可作為業(yè)務(wù)監(jiān)控使用;

          3. jmap dump 詳細(xì)分析jvm的內(nèi)存使用情況

          jmap dump,發(fā)現(xiàn)內(nèi)存異常,而其他方面沒(méi)啥思路時(shí),那就jvm內(nèi)存dump下來(lái),慢慢分析。
          dump整個(gè)內(nèi)存下來(lái),全量分析,jmap -dump:format=b,file=/tmp/a.dump . 然后就可以使用jvm內(nèi)存分析工具進(jìn)行分析了,如 mat 。分析工具的技巧可能還是需要去掌握下的,不過(guò)我這里簡(jiǎn)單提兩個(gè)點(diǎn),一個(gè)是看得到的堆內(nèi)存,一個(gè)是不可達(dá)的堆內(nèi)存,分析時(shí)就注意這兩點(diǎn)。一般可達(dá)堆內(nèi)存是很好分析的,不可達(dá)堆內(nèi)存則要憑借一定的經(jīng)驗(yàn)才能發(fā)現(xiàn)問(wèn)題了。

          對(duì)于快速查詢(xún),則直接在服務(wù)器上使用 jmap -heap 就可以查看了。

          jmap -dump:format=b,file=/tmp/a.dump <pid> # dump倒是堆內(nèi)存jmap -heap <pid> # 直接在服務(wù)器上查看堆的使用情況

          會(huì)一些OQL查詢(xún)語(yǔ)言,將會(huì)對(duì)你的排查如虎添翼! 

          4. lsof 列舉出正在使用的文件,看看是否能發(fā)現(xiàn)一些端倪

          lsof,這個(gè)工具用于排查是否存在很在很多超出預(yù)料的文件的情況,比如打開(kāi)某文件未關(guān)閉,建立很多的socket連接等等。當(dāng)然,發(fā)現(xiàn)問(wèn)題只能靠眼力勁了。

          lsof -p <pid> #查看進(jìn)程打開(kāi)的文件情況。

          lsof 使用詳細(xì)介紹參考網(wǎng)上資料: https://www.cnblogs.com/sparkbj/p/7161669.html

          5. pmap 查看進(jìn)程內(nèi)存概要

          pmap,用于查看進(jìn)程的內(nèi)存映像信息, 發(fā)現(xiàn)內(nèi)存中大塊的占用所在,以及分析內(nèi)存可能存在的異常。

          從中,你可以看到哪些內(nèi)存上面占用了多少內(nèi)存,正常的內(nèi)存如 JVM 所在內(nèi)存段,應(yīng)該是和你的堆內(nèi)存一致的,而其他內(nèi)存段,則是你看不到的地方,這些地方將是你排查內(nèi)存泄漏的方向。

          簡(jiǎn)要命令下:    pmap [ -x | -d ] [ -q ] pids...結(jié)果樣例如下:[root@abtest ~]# pmap -x 27466 27466:   /usr/local/jdk1.8.0_211/bin/java -Dzookeeper.log.dir=. -Dzookeeper.root.logger=INFO,CONSOLE -cp /opt/zookeeper/zookeeper-3.4.14/bin/../zookeeper-server/target/classes:/opt/zookeeper/zookeeper-3.4.14/bin/../build/classes:/opt/zookeeper/zookeeper-3.4.14/bin/../zookeeper-server/target/lib/*.jar:/opt/zookeeper/zookeeper-3.4.14/bin/../build/lib/*.jar:/opt/zookeeper/zookeeper-3.4.14/bin/../lib/slf4j-log4j12-1.7.25.jar:/opt/zookeeper/zookeeper-3.4.14/bin/../lib/slf4j-api-1.7.25.jar:/opt/zookeeper/zookeeper-3.4.1Address           Kbytes     RSS   Dirty Mode  Mapping0000000000400000       4       4       0 r-x-- java0000000000600000       4       4       4 r---- java0000000000601000       4       4       4 rw--- java...00007fff10253000     136      36      36 rw---   [ stack ]00007fff102ce000       8       4       0 r-x--   [ anon ]ffffffffff600000       4       0       0 r-x--   [ anon ]---------------- ------- ------- -------total kB         5421732  100608   87672

          命令操作詳情請(qǐng)參考網(wǎng)上資料:: https://www.cnblogs.com/txw1958/archive/2012/07/26/linux-pmap.html


          6. NMT,  nativeMemoryTracking jvm 的內(nèi)存追蹤工具

          nmt,這個(gè)jdk8以后,jvm提供的內(nèi)存跟蹤工具,nativeMemoryTracking, 可以用于排查內(nèi)存方案的問(wèn)題。 

          -XX:NativeMemoryTracking=summary     # 開(kāi)啟NMT追蹤jcmd 1 VM.native_memory summary        # 查看當(dāng)前的內(nèi)存概況jcmd 1 VM.native_memory baseline    # 創(chuàng)建基準(zhǔn) baselinejcmd 1 VM.native_memory summary.diff    # 一段時(shí)間后,比對(duì)內(nèi)存差異,可以用于發(fā)現(xiàn)內(nèi)存的走向問(wèn)題,如下[root@abtest ~]# jcmd 5545 VM.native_memory summary.diff5545:
          Native Memory Tracking:
          Total: reserved=5942859KB +2339KB, committed=4104347KB +1519KB
          - Java Heap (reserved=4194304KB, committed=3645440KB) (mmap: reserved=4194304KB, committed=3645440KB)
          - Class (reserved=1109328KB +2056KB, committed=66640KB +264KB) (classes #11172 +2) (malloc=1360KB +8KB #15153 +331) (mmap: reserved=1107968KB +2048KB, committed=65280KB +256KB)
          - Thread (reserved=133119KB, committed=133119KB) (thread #130) (stack: reserved=132544KB, committed=132544KB) (malloc=422KB #652) (arena=152KB #256)
          - Code (reserved=255919KB +247KB, committed=37519KB +1219KB) (malloc=6319KB +247KB #8248 +270) (mmap: reserved=249600KB, committed=31200KB +972KB)
          - GC (reserved=209075KB +8KB, committed=188707KB +8KB) (malloc=20659KB +8KB #28406 +320) (mmap: reserved=188416KB, committed=168048KB)
          - Compiler (reserved=277KB +5KB, committed=277KB +5KB) (malloc=146KB +5KB #592 +9) (arena=131KB #6)
          - Internal (reserved=12648KB, committed=12648KB) (malloc=12616KB #39090 +5) (mmap: reserved=32KB, committed=32KB)
          - Symbol (reserved=16444KB +8KB, committed=16444KB +8KB) (malloc=12569KB +8KB #121265 +2) (arena=3876KB #1)
          - Native Memory Tracking (reserved=3362KB +15KB, committed=3362KB +15KB) (malloc=18KB #204 +2) (tracking overhead=3344KB +15KB)
          - Arena Chunk (reserved=192KB, committed=192KB) (malloc=192KB)
          - Unknown (reserved=8192KB, committed=0KB) (mmap: reserved=8192KB, committed=0KB)

          如上結(jié)果,我們可以得得出些結(jié)論,隨著時(shí)間的推移, code 部分的占用空間增加了最多(JIT), Compiler 也增加一些,而堆內(nèi)存則一直保持不變!

          7. perf,這是一個(gè)性能監(jiān)控調(diào)優(yōu)工具,但是我們也可能從中發(fā)現(xiàn)內(nèi)存問(wèn)題點(diǎn)

          可以先捕獲數(shù)據(jù),然后進(jìn)行性能分析,然后得到可疑的點(diǎn)。

          幫助信息如下:

          usage: perf [--version] [--help] [OPTIONS] COMMAND [ARGS] The most commonly used perf commands are:   annotate        Read perf.data (created by perf record) and display annotated code   archive         Create archive with object files with build-ids found in perf.data file   bench           General framework for benchmark suites   buildid-cache   Manage build-id cache.   buildid-list    List the buildids in a perf.data file   c2c             Shared Data C2C/HITM Analyzer.   config          Get and set variables in a configuration file.   data            Data file related processing   diff            Read perf.data files and display the differential profile   evlist          List the event names in a perf.data file   ftrace          simple wrapper for kernel's ftrace functionality   inject          Filter to augment the events stream with additional information   kallsyms        Searches running kernel for symbols   kmem            Tool to trace/measure kernel memory properties   kvm             Tool to trace/measure kvm guest os   list            List all symbolic event types   lock            Analyze lock events   mem             Profile memory accesses   record          Run a command and record its profile into perf.data   report          Read perf.data (created by perf record) and display the profile   sched           Tool to trace/measure scheduler properties (latencies)   script          Read perf.data (created by perf record) and display trace output   stat            Run a command and gather performance counter statistics   test            Runs sanity tests.   timechart       Tool to visualize total system behavior during a workload   top             System profiling tool.   probe           Define new dynamic tracepoints   trace           strace inspired tool
          See 'perf help COMMAND' for more information on a specific command.

          簡(jiǎn)單示例:

              perf record -g -e cpu-clock -p 5545        # 記錄進(jìn)程 5545 的相關(guān)性能信息    perf report -i perf.data                # 讀取剛剛記錄的數(shù)據(jù),可以顯示出種操作的占用情況,如下Samples: 908  of event 'cpu-clock', Event count (approx.): 227000000  Children      Self  Command  Shared Object       Symbol+   32.27%     0.00%  java     libpthread-2.17.so  [.] start_thread+   32.27%     0.00%  java     libjvm.so           [.] java_start+   26.54%     0.00%  java     libjvm.so           [.] ConcurrentG1RefineThread::run+   26.54%     0.11%  java     libjvm.so           [.] ConcurrentG1RefineThread::run_young_rs_sampling+   25.77%     5.62%  java     libjvm.so           [.] YoungList::rs_length_sampling_next+   22.58%     0.55%  java     [kernel.kallsyms]   [k] tracesys+   11.01%     0.00%  java     perf-5545.map       [.] 0x00007f553ec1e981+   10.79%     0.44%  java     libjvm.so           [.] JVM_Sleep+    9.36%     0.55%  java     libjvm.so           [.] G1CollectorPolicy::update_incremental_cset_info+    8.70%     0.55%  java     libjvm.so           [.] os::sleep+    8.26%     0.00%  java     [unknown]           [k] 0xee83b0ac00709650+    8.15%     0.99%  java     libpthread-2.17.so  [.] pthread_cond_timedwait@@GLIBC_2.3.2+    7.93%     0.00%  java     perf-5545.map       [.] 0x00007f553f7f7d30

          如果運(yùn)氣碰巧的話(huà),你有可能能查到某些異常的操作,從而推斷出問(wèn)題所在。

          8. gdb 調(diào)試工具dump出可疑內(nèi)存

          gdb, linux下強(qiáng)大的調(diào)試工具,但是我們不用它來(lái)調(diào)試,我們只用來(lái)輸出內(nèi)存的內(nèi)容。即dump內(nèi)存,前面用到的jmap dump只能看到j(luò)vm的內(nèi)存信息,而gdb則可以看所有的,當(dāng)然我們會(huì)用來(lái)看其他部分的內(nèi)存。

              gdb attach <pid>                    # 先連接到進(jìn)程中    gdb dump memory /path/dump.bin 0x0011  0x0021    # dump 出內(nèi)存段的信息,具體要 dump 的內(nèi)存段地址,可以借助之前pmap 排查的結(jié)果,以及 cat /proc/<pid>/maps 中指示的地址段得出    strings /path/dump.bin | less # 查看內(nèi)存內(nèi)容, 相信你能從中發(fā)現(xiàn)一些不一樣的東西

          以上,足夠你排查出你懷疑的內(nèi)存泄露問(wèn)題了。如果不能,說(shuō)明你還用好工具,多練練!

          END


          推薦閱讀:

          世界的真實(shí)格局分析,地球人類(lèi)社會(huì)底層運(yùn)行原理

          企業(yè)IT技術(shù)架構(gòu)規(guī)劃方案

          論數(shù)字化轉(zhuǎn)型——轉(zhuǎn)什么,如何轉(zhuǎn)?

          企業(yè)10大管理流程圖,數(shù)字化轉(zhuǎn)型從業(yè)者必備!

          【中臺(tái)實(shí)踐】華為大數(shù)據(jù)中臺(tái)架構(gòu)分享.pdf

          華為的數(shù)字化轉(zhuǎn)型方法論

          華為如何實(shí)施數(shù)字化轉(zhuǎn)型(附PPT)

          超詳細(xì)280頁(yè)Docker實(shí)戰(zhàn)文檔!開(kāi)放下載

          華為大數(shù)據(jù)解決方案(PPT)


          瀏覽 65
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  草逼小视频 | 午夜黄网 | 围内精品久久久久久久久久98 | 欧美精品videos另类 | 极品人妻3p一人一次DVD |