Java命令:jmap — 打印指定進程的共享對象內存映射或堆內存細節

文章目錄

    • 一、前言
    • 二、命令介紹
    • 三、使用實例
      • 1、jmap -heap [pid]
      • 2、jmap -histo[:live] [pid]
      • 3、jmap -histo[:live] [pid] |grep "[關鍵字1]\|[關鍵字2]"
      • 4、jmap -dump:live,format=b,file=a.log [pid]
    • 四、總結

一、前言

jdk安裝后會自帶一些小工具,jmap命令(Java Memory Map)是其中之一。主要用于打印指定Java進程(或核心文件、遠程調試服務器)的共享對象內存映射或堆內存細節。

jmap 命令可以獲得運行中的jvm的堆的快照,從而可以離線分析堆,以檢查內存泄漏,檢查一些嚴重影響性能的大對象的創建,檢查系統中什么對象最多,各種對象所占內存的大小等等。可以使用jmap生成Heap Dump。

java memory = direct memory(直接內存) + jvm memory(MaxPermSize +Xmx)

1)直接內存跟堆

直接內存 則是一塊由程序本身管理的一塊內存空間,它的效率要比標準內存池要高,主要用于存放網絡通信時數據緩沖和磁盤數據交換時的數據緩沖。

DirectMemory 容量可以通過 -XX:MaxDirectMemorySize 指定,如果不指定,則默認為與Java堆的最大值(-Xmx指定)一樣。但是,在OSX上的最新版本的 JVM,對直接內存的默認大小進行修訂,改為“在不指定直接內存大小的時默認分配的直接內存大小為64MB”,可以通過 -XX:MaxMemorySize 來顯示指定直接內存的大小。

2)堆(Heap)和非堆(Non-heap)內存

按照官方的說法:“Java 虛擬機具有一個堆,堆是運行時數據區域,所有類實例和數組的內存均從此處分配。堆是在 Java 虛擬機啟動時創建的。”“在JVM中堆之外的內存稱為非堆內存(Non-heap memory)”。

可以看出JVM主要管理兩種類型的內存:堆和非堆

  • 就是Java代碼可及的內存,是留給開發人員使用的;
  • 非堆 就是JVM留給自己用的。

所以方法區、JVM內部處理或優化所需的內存(如JIT編譯后的代碼緩存)、每個類結構(如運行時常數池、字段和方法數據)以及方法和構造方法的代碼都在非堆內存中。

3)棧與堆

棧解決程序的運行問題,即程序如何執行,或者說如何處理數據;堆解決的是數據存儲的問題,即數據怎么放、放在哪兒。

在Java中一個線程就會相應有一個線程棧與之對應,這點很容易理解,因為不同的線程執行邏輯有所不同,因此需要一個獨立的線程棧。而堆則是所有線程共享的。棧因為是運行單位,因此里面存儲的信息都是跟當前線程(或程序)相關信息的。包括局部變量、程序運行狀態、方法返回值等等;而堆只負責存儲對象信息。

Java的堆是一個運行時數據區,類的(對象從中分配空間。這些對象通過new、newarray、anewarray和multianewarray等 指令建立,它們不需要程序代碼來顯式的釋放。堆是由垃圾回收來負責的,堆的優勢是可以動態地分配內存大小,生存期也不必事先告訴編譯器,因為它是在運行時 動態分配內存的,Java的垃圾收集器會自動收走這些不再使用的數據。但缺點是,由于要在運行時動態分配內存,存取速度較慢。 棧的優勢是,存取速度比堆要快,僅次于寄存器,棧數據可以共享。但缺點是,存在棧中的數據大小與生存期必須是確定的,缺乏靈活性。棧中主要存放一些基本類 型的變量(,int, short, long, byte, float, double, boolean, char)和對象句柄。

線程占用大小在MaxPermSize中進行內存申請和分配。


二、命令介紹

Usage:jmap [option] <pid>(to connect to running process)jmap [option] <executable <core>(to connect to a core file)jmap [option] [server_id@]<remote server IP or hostname>(to connect to remote debug server)where <option> is one of:<none>               to print same info as Solaris pmap-heap                to print java heap summary-histo[:live]        to print histogram of java object heap; if the "live"suboption is specified, only count live objects-clstats             to print class loader statistics-finalizerinfo       to print information on objects awaiting finalization-dump:<dump-options> to dump java heap in hprof binary formatdump-options:live         dump only live objects; if not specified,all objects in the heap are dumped.format=b     binary formatfile=<file>  dump heap to <file>Example: jmap -dump:live,format=b,file=heap.bin <pid>-F                   force. Use with -dump:<dump-options> <pid> or -histoto force a heap dump or histogram when <pid> does notrespond. The "live" suboption is not supportedin this mode.-h | -help           to print this help message-J<flag>             to pass <flag> directly to the runtime system

注:

  • -heap:打印jvm heap的情況
  • -histo:打印jvm heap的直方圖。其輸出信息包括類名,對象數量,對象占用大小。
  • -histo:live :同上,但是只答應存活對象的情況
  • -permstat:打印permanent generation heap情況

三、使用實例

1、jmap -heap [pid]

展示pid的整體堆信息。

首先啟動一個tomcat,然后使用如下命令獲取tomcat的進程ID。

ps -ef|grep tomcat

在這里插入圖片描述
然后執行:

jmap -heap 86038

輸出內容:

Attaching to process ID 86038, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.121-b13using thread-local object allocation.
Parallel GC with 4 thread(s)Heap Configuration:         # 堆內存初始化配置MinHeapFreeRatio         = 0                        # -XX:MinHeapFreeRatio設置JVM堆最小空閑比率  MaxHeapFreeRatio         = 100                      # -XX:MaxHeapFreeRatio設置JVM堆最大空閑比率  MaxHeapSize              = 2147483648 (2048.0MB)    # -XX:MaxHeapSize=設置JVM堆的最大大小NewSize                  = 44564480 (42.5MB)        # -XX:NewSize=設置JVM堆的‘新生代’的默認大小MaxNewSize               = 715653120 (682.5MB)      # -XX:MaxNewSize=設置JVM堆的‘新生代’的最大大小OldSize                  = 89653248 (85.5MB)        # -XX:OldSize=設置JVM堆的‘老生代’的大小NewRatio                 = 2                        # -XX:NewRatio=:‘新生代’和‘老生代’的大小比率SurvivorRatio            = 8                        # -XX:SurvivorRatio=設置年輕代中Eden區與Survivor區的大小比值MetaspaceSize            = 21807104 (20.796875MB)   CompressedClassSpaceSize = 1073741824 (1024.0MB)    MaxMetaspaceSize         = 17592186044415 MB        G1HeapRegionSize         = 0 (0.0MB)Heap Usage:
PS Young Generation
Eden Space:           # Eden區內存分布capacity = 426770432 (407.0MB)used     = 79056192 (75.39385986328125MB)free     = 347714240 (331.60614013671875MB)18.524289892698096% used
From Space:           # 其中一個Survivor區的內存分布capacity = 30932992 (29.5MB)used     = 0 (0.0MB)free     = 30932992 (29.5MB)0.0% used
To Space:             # 另一個Survivor區的內存分布capacity = 31457280 (30.0MB)used     = 0 (0.0MB)free     = 31457280 (30.0MB)0.0% used
PS Old Generationcapacity = 72351744 (69.0MB)used     = 21741336 (20.734153747558594MB)free     = 50610408 (48.265846252441406MB)30.049498184867527% used16180 interned Strings occupying 2074344 bytes.

2、jmap -histo[:live] [pid]

展示class的內存情況。

jmap -histo 86038

執行結果:

 num     #instances         #bytes  class name
----------------------------------------------1:          7287       46167552  [I2:         78166       33933008  [B3:        221419       25746168  [C4:        116110        2786640  java.lang.String5:         11708         886224  [Ljava.lang.Object;6:         18869         603808  java.util.HashMap$Node7:         24275         582600  java.lang.StringBuilder8:          6464         568832  java.lang.reflect.Method9:          4715         541352  java.lang.Class10:          4847         418760  [S11:          1686         391288  [Ljava.util.HashMap$Node;...

注:

  • instances:實例數;
  • bytes:內存占用大小;
  • classs name:類名。

它基本是按照使用使用大小逆序排列的。

jmap -histo:live 86038

獲取所有生存的對象的內存情況。

注:

  • 該命令獲取的結果與jmap -histo [pid]獲取結果一致;
  • 執行jmap -histo:live [pid]時,JVM會先觸發gc,然后再統計信息

從打印結果可看出,類名中存在[C、[B等內容,只知道它占用了那么大的內存,但不知道由什么對象創建的。下一步需要將其他dump出來,使用內存分析工具進一步明確它是由誰引用的、由什么對象。

另外可以執行如下命令將打印內容保存到文件中。

jmap -histo:live 86038>a.log

通過對多次打印內容的對比,可以對比出GC回收了哪些對象。


3、jmap -histo[:live] [pid] |grep “[關鍵字1]|[關鍵字2]”

展示指定關鍵字的類的內存情況。

jmap -histo:live 86038 | grep "java.util.\|java.lang."

執行結果:

 num     #instances         #bytes  class name
----------------------------------------------6:         18869         603808  java.util.HashMap$Node7:         24275         582600  java.lang.StringBuilder8:          6464         568832  java.lang.reflect.Method9:          4715         541352  java.lang.Class...

從執行結果看,打印出了類全路徑名稱中包含 java.util.java.lang. 的所有類內存情況。

注:匹配多個關鍵字之間用 \| 隔開。


4、jmap -dump:live,format=b,file=a.log [pid]

內存信息dump到a.log文件中。

這個命令執行,JVM會將整個heap的信息dump寫入到一個文件,heap如果比較大的話,就會導致這個過程比較耗時,并且執行的過程中為了保證dump的信息是可靠的,所以會暫停應用

該命令通常用來分析內存泄漏OOM,通常做法是:

1)首先配置JVM啟動參數,讓JVM在遇到OutOfMemoryError時自動生成Dump文件

-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path

2)然后使用命令

// 如果只dump heap中的存活對象,則加上選項-live。
jmap -dump:format=b,file=/path/heap.bin [pid]

四、總結

  • 1、如果程序內存不足或者頻繁GC,很有可能存在內存泄露情況,這時候就要借助Java堆Dump查看對象的情況。

  • 2、要制作堆Dump可以直接使用jvm自帶的jmap命令

  • 3、可以先使用jmap -heap命令查看堆的使用情況,看一下各個堆空間的占用情況。

  • 4、使用jmap -histo:[live]查看堆內存中的對象的情況。如果有大量對象在持續被引用,并沒有被釋放掉,那就產生了內存泄露,就要結合代碼,把不用的對象釋放掉。

  • 5、也可以使用 jmap -dump:format=b,file=命令將堆信息保存到一個文件中,再借助jhat命令查看詳細內容

  • 6、在內存出現泄露、溢出或者其它前提條件下,建議多dump幾次內存,把內存文件進行編號歸檔,便于后續內存整理分析。

  • 7、在用cms gc的情況下,執行jmap -heap有些時候會導致進程變T,因此強烈建議別執行這個命令,如果想獲取內存目前每個區域的使用狀況,可通過jstat -gc或jstat -gccapacity來拿到。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/446877.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/446877.shtml
英文地址,請注明出處:http://en.pswp.cn/news/446877.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C++vector相關學習,我的理解

vector的初始化方式 1&#xff0c;使用拷貝初始化時候&#xff0c;即使用的時候&#xff0c;只可以提供一個初始值2&#xff0c;如果提供一個類內初始值&#xff0c;只可以使用拷貝初始化或者使用花括號的方式初始化3&#xff0c;如果提供的是初始元素值的列表&#xff0c;只可…

概率論 一維隨機變量

隨機變量 離散型隨機變量:有限個或無限可列個 連續型隨機變量 分布函數F(X) 范圍是[a,b) 包含能取到a以及a之前的值的概率相加 分布律(概率分布) 1.所有概率相加為1 2.WX-1,計算出每一個對應的W,然后如果有相同的W就合并其概率,最后一一對應P(x)即可 概率密度函數(密度) …

Linux命令:grep命令詳解

grep常用參數說明 grep [OPTIONS] PATTERN [FILE...] grep [OPTIONS] [-e PATTERN]... [-f FILE]... [FILE...]OPTIONS:-e: 使用正則搜索-i: 不區分大小寫-v: 查找不包含指定內容的行-w: 按單詞搜索-c: 統計匹配到的次數-n: 顯示行號-r: 逐層遍歷目錄查找-A: 顯示匹配行及后…

ECC密鑰結構和密碼學基礎

參考鏈接 密碼學基礎3&#xff1a;密鑰文件格式完全解析ECC數據結構

JAVA牛客專項練習2020.12.31

1.使用迭代器的remove方法&#xff0c;可以邊遍歷邊刪除元素 2.線程 啟動線程 new thread&#xff08;&#xff09;.start&#xff08;&#xff09; new thread&#xff08;new runnable&#xff08;&#xff09;&#xff09;.start&#xff08;&#xff09; 普通方法&#xf…

Linux命令:find命令詳解

find命令格式 find path -option [-print] [-exec -ok |xargs |grep] [command {} \;]# 參數說明path: find命令所查找的目錄路徑。~ 表示$HOME目錄;.來表示當前目錄;/來表示系統根目錄。-print: find命令將匹配的文件輸出到標準輸出。-exec: find命令對匹配的文件執行該參數所…

boost::interprocess::named_mutex的翻譯和學習

官方地址 named_mutex 簡介 // In header: <boost/interprocess/sync/named_mutex.hpp>class named_mutex { public:// construct/copy/destruct 構建/復制/銷毀named_mutex(create_only_t, const char *, const permissions & permissions());named_mutex(open_o…

安卓牛客專項練習2020.12.31

1.窗口dialog或半透明 2.Pracelable性能比serializable高

MAC查找JDK的路徑

在控制臺中輸入&#xff1a; /usr/libexec/java_home -V輸出如下結果&#xff1a; Matching Java Virtual Machines (4):1.8.0_121, x86_64: "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home1.7.0_79, x86_64: "Java SE 7&quo…

sqliteorm的sync_schema介紹

遷移功能 在遷移過程中&#xff0c;沒有明確的上下函數。取而代之的是sqlite_orm提供的sync_schema函數&#xff0c;它負責將實際的db文件模式和你在make_storage調用中指定的模式進行比較&#xff0c;如果有什么不一樣&#xff0c;它就會改變或放棄/創建模式。 storage.sync_…

安卓系統體系架構

1.大體:共有四層&#xff0c;系統應用層&#xff0c;JAVA API層&#xff0c;安卓系統運行層&#xff0c;Linux內核層 具體: 系統應用層&#xff08;System Apps&#xff09; Java API 框架層&#xff08;Java API Framework&#xff09; Android系統運行層&#xff08;包括Andr…

Java命令:jstack — 獲取線程dump信息

目錄一、命令介紹二、使用實例實例一&#xff1a;jstack查看輸出實例二&#xff1a;jstack統計線程數實例三&#xff1a;jstack檢測死鎖實例四&#xff1a;jstack檢測CPU高一、命令介紹 Usage:jstack [-l] <pid>(to connect to running process) //連接活動線程jstack …

Java多線程死鎖例子

目錄一、產生死鎖的原因二、如何避免死鎖一、產生死鎖的原因 發生死鎖的情況&#xff1a; 多個線程需要同時占用多個共享資源而發生需要互相死循環等待的情況&#xff0c;就是&#xff0c;兩個線程互相等待著對象釋放鎖&#xff0c;一直這樣僵持下去&#xff0c;所以導致了死鎖…

C++中lock_guard的學習

lock_guard 鎖守衛是一個管理mutex對象的對象&#xff0c;使其始終處于鎖定狀態。在構造時&#xff0c;mutex對象被調用線程鎖定&#xff0c;在銷毀時&#xff0c;mutex被解鎖。這是最簡單的鎖&#xff0c;作為一個自動持續時間的對象&#xff0c;它的作用特別大&#xff0c;可…

安卓四大組件簡介

安卓四大組件 Activity活動&#xff0c;Service服務&#xff0c;BroadcastRecevicer廣播接受器&#xff0c;Content Provider內容提供者 Activity活動 所有程序的流程都運行在activity中 Service服務 只能后臺運行&#xff0c;沒有界面的長生命周期的代碼 BroadcastRece…

WebLogic域的創建與發布

目錄一、前言二、準備三、創建域步驟第一步&#xff1a;直接【回車】第二步&#xff1a;直接【回車】第三步&#xff1a;直接【回車】第四步&#xff1a;輸入域名稱后【回車】第五步&#xff1a;直接【回車】第六步&#xff1a;直接【回車】&#xff08;此步驟是提示域的存放目…

安卓安卓移動操作系統優缺點

安卓移動操作系統優缺點 開發性 豐富的硬件 方便開發 gogle應用 安卓模擬器 手機,手表,電視,車載,安卓cel LogCat的使用–5級(日志) Log.v()–verbose全部信息,黑色 Log.d()–debug調試信息,藍色 Log.i()–info一般信息,綠色 Log.w()–warning警告信息,橙色 Log.e()–erro…

WebLogic啟動失敗:java.lang.AssertionError: Could not obtain the localhost address.

目錄一、錯誤信息二、解決方案第一步&#xff1a;查看本機計算機名稱第二步&#xff1a;編輯hosts文件一、錯誤信息 linux下啟動WebLogic報如下錯誤&#xff1a; 二、解決方案 此錯誤多半是hosts文件不對導致的。 解決步驟如下&#xff1a; 第一步&#xff1a;查看本機計…

sqlite_orm sync_schema源碼即翻譯

源碼 /*** This is a cute function used to replace migration up/down functionality.* It performs check storage schema with actual db schema and:* * if there are excess tables exist in db they are ignored (not dropped)* * every table from storage is comp…

安卓布局UI簡介

安卓UI 用戶界面UI&#xff08;使用者界面&#xff09; ——系統和用戶之間進行交互和信息交換的媒體 由布局和組件組成 軟件設計&#xff1a;編碼設計和UI設計 布局 ——可定義應用中的界面結構 所有元素都使用View和Viewgroup對象的層次結構進行構建 view微件——構建用戶…