{"id":3441,"date":"2014-08-09T11:18:32","date_gmt":"2014-08-09T03:18:32","guid":{"rendered":"http:\/\/rmohan.com\/?p=3441"},"modified":"2014-08-09T11:31:21","modified_gmt":"2014-08-09T03:31:21","slug":"jmap-histo-thread-dump-cpu-utilization","status":"publish","type":"post","link":"https:\/\/mohan.sg\/?p=3441","title":{"rendered":"JMAP, HISTO, Thread Dump, CPU Utilization"},"content":{"rendered":"<p>Dear Reader,<\/p>\n<p>In a production environment Java Profiling is not an option, we have seen multiple times that<br \/>\nour CPU has reached almost 100% or even 300% sometime. That is really a panic scenario especially<br \/>\nwhen you are handling production environment or at client place to check what went wrong.<\/p>\n<p>Fortunately, Java comes with some great debugging tools, co-operating those tools with Linux<br \/>\nbuilt-in tools will help you to know what is happening.<\/p>\n<p>I am going to explain below items here:<br \/>\n    1) An introduction about Java threads and its relation to Linux LWP (Light Weight Process).<br \/>\n    2) Step-by-step process to take thread dump and analyze CPU utilization.<br \/>\n    3) &#8220;jmap&#8221; &#8211; Memory Map (dump), Command to get this.<br \/>\n    4) &#8220;jmap&#8221; &#8211; Histo, Command to get this.<br \/>\n    5) Command to see list of open files in Unix.<\/p>\n<p>1) Introduction: Any java program starts when the JVM calls the main method, this creates a thread<br \/>\n    called the main thread and any thread you create using java code will be derived from the main<br \/>\n    thread. The same exact behavior occurs on the Linux level, the main thread for java means a Process<br \/>\n    for the OS and every thread you create using java the OS will create a Light-weight-process<br \/>\n    or LWP. In short: Java main thread = Linux process and Java supporting threads = Linux LWP.<\/p>\n<p>    The idea here:<br \/>\n        Ask Linux which LWP is eating the CPU.<br \/>\n        Ask Java for a Thread Dump.<br \/>\n        Map this LWP to a Java thread.<br \/>\n        Get the part of code causing the issue.    <\/p>\n<p>2) Step-by-step process:<br \/>\n        Get the PID: the very first step is to know what is the Java process ID, we will use Linux commands<br \/>\n        as below. Use either of the below commands (we use our grep &#8220;DAPPNAME&#8221;, you can use anything):<br \/>\n        jps -v | cut -c -106 | grep DAPPNAME<br \/>\n        jps -mvl | cut -c -106 | grep DAPPNAME<br \/>\n        ps -eaf | cut -c -106 | grep DAPPNAME<br \/>\n        ps -ef | cut -c -106 | grep DAPPNAME<br \/>\n        ps -eaf | grep java<\/p>\n<p>        Below are the sample output when you execute the command:<br \/>\n        dmodi@MyDirectory:~$ jps -mlv | cut -c -106 | grep DAPPNAME<br \/>\n        8243 org.quickserver.net.server.QuickServer -load config\/DmodiServer.xml -DAPPNAME=CLIENT<br \/>\n        13712 org.quickserver.net.server.QuickServer -load .\/conf\/DmodiDNXServer.xml -DAPPNAME=SERVER<br \/>\n        12229 org.quickserver.net.server.QuickServer -load .\/config\/DmodiPOSServer.xml -DAPPNAME=SERVER2<\/p>\n<p>        Explanation: &#8220;jps&#8221; &#8211; Java Virtual Machine Process Status Tool, a command in Unix. &#8220;106&#8221; shows 106<br \/>\n        characters we want to display in console.<\/p>\n<p>        The next step is to get the CPU usage per each LWP related to the main process, we can use below commands:<br \/>\n         ps -eLo pid,lwp,nlwp,ruser,pcpu,stime,etime,args | grep PROCESS_ID | cut -c -106 > threadsList.txt<\/p>\n<p>        The newly created file threadsList.txt will contain below things in similar way (The headers will not be<br \/>\n        shown as below):<br \/>\n        PID   LWP  NLWP RUSER    %CPU STIME  ELAPSED     COMMAND<br \/>\n        8243  8243 3  dmodi  0.0 May13  1-19:20:18 java -Dprogram.name=run.sh -Xms64m -Xmx100m -Dsun.rmi.dgc<br \/>\n        8243  8244 3  dmodi  0.0 May13  1-19:20:18 java -Dprogram.name=run.sh -Xms64m -Xmx100m -Dsun.rmi.dgc<br \/>\n        8243  8245 3  dmodi 99.9 May13  1-19:20:18 java -Dprogram.name=run.sh -Xms64m -Xmx100m -Dsun.rmi.dgc<\/p>\n<p>         To see headers too, just execute the below command:<br \/>\n         ps -eLo pid,lwp,nlwp,ruser,pcpu,stime,etime,args > threadsList.txt<\/p>\n<p>         Explanation: PID is process Id.<br \/>\n            LWP: is Light weight processes Lists for the above PID. These values are in Decimal.<br \/>\n            NLWP: is number of LWP created for the above PID.<br \/>\n            Rest other headers don&#8217;t require any explanation.<br \/>\n            We can see LWP &#8211; 8245 is eating CPU. We need to convert this value into HEX value which will be &#8220;2035&#8221;.<\/p>\n<p>        Now take the thread dump and kill the process Id: 8243. Open the thread dump file and search value &#8220;2035&#8221;.<br \/>\n        See below command:<br \/>\n        \/\/Taking thread dump<br \/>\n        jstack -l 8243 > ThreadDump_15_May_2014_13_PM.txt<\/p>\n<p>        \/\/Killing process<br \/>\n        kill -9 8243<\/p>\n<p>3) &#8220;jmap&#8221; &#8211; Memory Map (dump): Prints shared object memory maps or heap memory details of a given JVM process.<br \/>\n        dmodiUnixUser@productName79:~$ jmap -dump:file=deepak.bin 8243<br \/>\n        Dumping heap to \/home\/dmodiUnixUser\/deepak.bin &#8230;<br \/>\n        Heap dump file created<br \/>\n        dmodiUnixUser@productName79:~$ ls<br \/>\n        deepak.bin<br \/>\n        This newly created file will be big in size (of 5-10 MB around). You can&#8217;t see this content using<br \/>\n        &#8220;less&#8221; or &#8220;cat&#8221; command. You need tool to see this. We don&#8217;t use this generally, so not mentioning here.<\/p>\n<p>4) &#8220;jmap&#8221; &#8211; Histo: See below command:<br \/>\n        dmodiUnixUser@productName79:~$ jmap -histo:live 8243 > deepak.txt<br \/>\n        Contents of this file &#8220;deepak.txt&#8221; will have similar like above:<\/p>\n<p>        num     #instances         #bytes  class name<br \/>\n        &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br \/>\n        1:         14452        2229096  <constMethodKlass><br \/>\n        2:         14452        1740720  <methodKlass><br \/>\n        3:          1004        1406296  <constantPoolKlass><br \/>\n        4:          1336        1270504  [B<br \/>\n        5:         25057        1060840  <symbolKlass><br \/>\n        6:           835         809368  <constantPoolCacheKlass><br \/>\n        7:          1004         787096  <instanceKlassKlass><\/p>\n<p>5) List of open files in Linux:<br \/>\n    lsof &#8211; list open files<br \/>\n    dmodiUnixUser@productName79:~$ lsof | grep home\/dmodi\/productName\/dist\/<br \/>\n    COMMAND   PID  USER             FD     TYPE   DEVICE  SIZE\/OFF  NODE  NAME<br \/>\n    java    16460  dmodiUnixUser  mem    REG    9,2     25680 8127062 home\/dmodi\/productName\/dist\/sample1.jar<br \/>\n    java    16460  dmodiUnixUser  mem    REG    9,2     66770 8127061 home\/dmodi\/productName\/dist\/sample2.jar<\/p>\n<p>    dmodiUnixUser@productName79:~$ lsof | grep PROCESS_ID > help.txt<br \/>\n    dmodiUnixUser@productName79:~$ less help.txt<br \/>\n&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-END&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Dear Reader,<\/p>\n<p>In a production environment Java Profiling is not an option, we have seen multiple times that our CPU has reached almost 100% or even 300% sometime. That is really a panic scenario especially when you are handling production environment or at client place to check what went wrong.<\/p>\n<p>Fortunately, Java comes with some [&#8230;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[18,4,21],"tags":[],"_links":{"self":[{"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/posts\/3441"}],"collection":[{"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mohan.sg\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3441"}],"version-history":[{"count":1,"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/posts\/3441\/revisions"}],"predecessor-version":[{"id":3442,"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/posts\/3441\/revisions\/3442"}],"wp:attachment":[{"href":"https:\/\/mohan.sg\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3441"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mohan.sg\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3441"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mohan.sg\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3441"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}