查看JAVA进程PID。
jps命令用来查看所有Java进程,每一行就是一个Java进程信息。
jps仅查找当前用户的Java进程,而不是当前系统中的所有进程,要显示其他用户的还只能用ps命令。
jps常用参数
jps-l如果是以class方式运行,会显示进程的主类的全名,如果是以jar包方式运行的,就会输出jar包的完整路径名
第一列的数字就是进程的pid
jps-v输出传递给JVM的参数,v表示虚拟机,jps-vl比较常见的组合;
jps-V大写v,表示通过文件传递给JVM的参数
Copyjinfo--helpUsage:jinfo[option]pid(toconnecttorunningprocess)jinfo[option]executablecore(toconnecttoacorefile)jinfo[option][server_id@]remoteserverIPorhostname(toconnecttoremotedebugserver)whereoptionisoneof:-flagnametoprintthevalueofthenamedVMflag-flag[+|-]nametoenableordisablethenamedVMflag-flagname=valuetosetthenamedVMflagtothegivenvalue-flagstoprintVMflags-syspropstoprintJavasystempropertiesnooptiontoprintbothoftheabove-h|-helptoprintthishelpmessage
我们先用jps命令查到PID,然后可以通过jinfo来查看对应进程的参数信息:
[root@admin~]jinfo-flags43520AttachingtoprocessID43520,=GBK
查看系统参数:
[root@admin~]jinfo-flagPrintGC43520-XX:-PrintGC[root@admin~]453daemonprio=9os_prio=0tid=0x00007f9f94001000nid=0xf30waitingoncondition[0x0000000000000000]:RUNNABLELockedownablesynchronizers:-None"grpc-default-executor-263"235daemonprio=5os_prio=0tid=0x0000000001bcc800nid=0x3c13waitingoncondition[0x00007f9f384a9000]:WAITING(parking)(NativeMethod)-parkingtowaitfor0x0000000743d26638($ConditionObject)(:175)$(:2039)(:442)(:104)(:32)(:1067)(:1127)$(:617)$(:61)(:745)Lockedownablesynchronizers:-None
jstack统计线程数
/opt/java8/bin/jstack-l28367|grep''|wc-l
jstack检测死锁
死锁代码
publicclassDeathLock{privatestaticLocklock1=newReentrantLock();privatestaticLocklock2=newReentrantLock();publicstaticvoiddeathLock(){Threadt1=newThread(){@Overridepublicvoidrun(){try{();(1);();}catch(InterruptedExceptione){();}}};Threadt2=newThread(){@Overridepublicvoidrun(){try{();(1);();}catch(InterruptedExceptione){();}}};("thread1");("thread2");();();}publicstaticvoidmain(String[]args){deathLock();}}死锁日志
"mythread2"11prio=5os_prio=0tid=0x0000000058ef7000nid=0x3e68waitingoncondition[0x000000005947f000]:WAITING(parking)(NativeMethod)-parkingtowaitfor0x00000000d602d640($NonfairSync)(:175)(:836)(:870)(:1199)$(:209)(:285)atDeathLock$1.run(:22)Lockedownablesynchronizers:-0x00000000d602d610($NonfairSync)FoundoneJava-leveldeadlock:============================="mythread2":waitingforownablesynchronizer0x00000000d602d610,($NonfairSync),whichisheldby"mythread1""mythread1":waitingforownablesynchronizer0x00000000d602d640,($NonfairSync),whichisheldby"mythread2"Javastackinformationforthethreadslistedabove:==================================================="mythread2":(NativeMethod)-parkingtowaitfor0x00000000d602d610($NonfairSync)(:175)(:836)(:870)(:1199)$(:209)(:285)atDeathLock$2.run(:34)"mythread1":(NativeMethod)-parkingtowaitfor0x00000000d602d640($NonfairSync)(:175)(:836)(:870)(:1199)$(:209)(:285)atDeathLock$1.run(:22)Found1deadlock.
jstack检测cpu高
步骤一:查看cpu占用高进程
topMem:16333644ktotal,9472968kused,6860676kfree,165616kbuffersSwap:0ktotal,0kused,0kfree,6665292kcachedPIDUSERPRNIVIRTRESSHRS%CPU%MEMTIME+:53.80:37.75:30.20:00.81:00.00:00.14migration/0
步骤二:查看cpu占用高线程
top-H-p17850top-17:43:15up5days,7:31,1user,loadaverage:0.99,0.97,0.91Tasks:32total,1running,31sleeping,0stopped,0zombieCpu(s):3.7%us,8.9%sy,0.0%ni,87.4%id,0.0%wa,0.0%hi,0.0%si,0.0%stMem:16333644ktotal,9592504kused,6741140kfree,165700kbuffersSwap:0ktotal,0kused,0kfree,6781620kcachedPIDUSERPRNIVIRTRESSHRS%CPU%MEMTIME+:47.43:02.08:00.00:00.23:02.09:02.12:02.07java
步骤三:转换线程ID
printf"%x\n"1788045d8
步骤四:定位cpu占用线程
jstack17850|grep45d8-A30"pool-1-thread-11"19prio=5os_prio=0tid=0x00007fc860345000nid=0x45d7waitingoncondition[0x00007fc8418d3000]:WAITING(parking)(NativeMethod)-parkingtowaitfor0x00000006c6c14178($ConditionObject)(:175)Jmap
原文参考:
什么是堆Dump基础知识Java虚拟机的内存组成以及堆内存介绍JavaGC工作原理
常见内存错误:
jmap用法摘要
Usage:jmap[option]pid(toconnecttorunningprocess)jmap[option]executablecore(toconnecttoacorefile)jmap[option][server_id@]remoteserverIPorhostname(toconnecttoremotedebugserver)whereoptionisoneof:nonetoprintsameinfoasSolarispmap-heaptoprintjavaheapsummary-histo[:live]toprinthistogramofjavaobjectheap;ifthe"live"suboptionisspecified,onlycountliveobjects-permstattoprintpermanentgenerationstatistics-finalizerinfotoprintinformationonobjectsawaitingfinalization-dump:dump-optionstodumpjavaheapinhprofbinaryformatdump-options:livedumponlyliveobjects;ifnotspecified,=bbinaryformatfile=filedumpheaptofileExample:jmap-dump:live,format=b,file=:dump-opt"live"suboptionisnotsupportedinthismode.-h|-helptoprintthishelpmessage-Jflagtopassflagdirectlytotheruntimesystem
指定进程号(pid)的进程jmap[option]
指定核心文件jmap[option]
指定远程调试服务器jmap[option][server-id@]
参数:
option选项参数是互斥的(不可同时使用)。想要使用选项参数,直接跟在命令名称后即可。
pid需要打印配置信息的进程ID。该进程必须是一个Java进程。想要获取运行的Java进程列表,你可以使用jps。
executable产生核心dump的Java可执行文件。
core需要打印配置信息的核心文件。
remote-hostname-or-IP远程调试服务器的(请查看jsadebugd)主机名或IP地址。
server-id可选的唯一id,如果相同的远程主机上运行了多台调试服务器,用此选项参数标识服务器。
选项:
如果使用不带选项参数的jmap打印共享对象映射,将会打印目标虚拟机中加载的每个共享对象的起始地址、映射大小以及共享对象文件的路径全称。这与Solaris的pmap工具比较相似。
-dump:[live,]format=b,file=以hprof二进制格式转储Java堆到指定filename的文件中。live子选项是可选的。如果指定了live子选项,堆中只有活动的对象会被转储。想要浏览heapdump,你可以使用jhat(Java堆分析工具)读取生成的文件。
-finalizerinfo打印等待终结的对象信息。
-heap打印一个堆的摘要信息,包括使用的GC算法、堆配置信息和generationwiseheapusage。
-histo[:live]打印堆的柱状图。其中包括每个Java类、对象数量、内存大小(单位:字节)、完全限定的类名。打印的虚拟机内部的类名称将会带有一个’*’前缀。如果指定了live子选项,则只计算活动的对象。
-permstat打印Java堆内存的永久保存区域的类加载器的智能统计信息。对于每个类加载器而言,它的名称、活跃度、地址、父类加载器、它所加载的类的数量和大小都会被打印。此外,包含的字符串数量和大小也会被打印。
-F强制模式。如果指定的pid没有响应,请使用jmap-dump或jmap-histo选项。此模式下,不支持live子选项。
-h打印帮助信息。
-help打印帮助信息。
-J指定传递给运行jmap的JVM的参数。
示例:
查看java堆(heap)使用情况,执行命令:jmap-heap31846
AttachingtoprocessID31846,(s)//GC方式HeapConfiguration://堆内存初始化配置MinHeapFreeRatio=0//对应jvm启动参数-XX:MinHeapFreeRatio设置JVM堆最小空闲比率(default40)MaxHeapFreeRatio=100//对应jvm启动参数-XX:MaxHeapFreeRatio设置JVM堆最大空闲比率(default70)MaxHeapSize=2082471936(1986.0MB)//对应jvm启动参数-XX:MaxHeapSize=设置JVM堆的最大大小NewSize=1310720(1.25MB)//对应jvm启动参数-XX:NewSize=设置JVM堆的‘新生代’的默认大小MaxNewSize=415MB//对应jvm启动参数-XX:MaxNewSize=设置JVM堆的‘新生代’的最大大小OldSize=5439488(5.1875MB)//对应jvm启动参数-XX:OldSize=value:设置JVM堆的‘老生代’的大小NewRatio=2//对应jvm启动参数-XX:NewRatio=:‘新生代’和‘老生代’的大小比率SurvivorRatio=8//对应jvm启动参数-XX:SurvivorRatio=设置年轻代中Eden区与Survivor区的大小比值PermSize=21757952(20.75MB)//对应jvm启动参数-XX:PermSize=value:设置JVM堆的‘永生代’的初始大小MaxPermSize=85983232(82.0MB)//对应jvm启动参数-XX:MaxPermSize=value:设置JVM堆的‘永生代’的最大大小G1HeapRegionSize=0(0.0MB)HeapUsage://堆内存使用情况PSYoungGenerationEdenSpace://Eden区内存分布capacity=33030144(31.5MB)//Eden区总容量used=1524040(1.4534378051757812MB)//Eden区已使用free=31506104(30.04656219482422MB)//Eden区剩余容量4.6305%used//Eden区使用比率FromSpace://其中一个Survivor区的内存分布capacity=5242880(5.0MB)used=0(0.0MB)free=5242880(5.0MB)0.0%usedToSpace://另一个Survivor区的内存分布capacity=5242880(5.0MB)used=0(0.0MB)free=5242880(5.0MB)0.0%usedPSOldGeneration//当前的Old区内存分布capacity=86507520(82.5MB)used=0(0.0MB)free=86507520(82.5MB)0.0%usedPSPermGeneration//当前的“永生代”内存分布capacity=22020096(21.0MB)used=2496528(2.3808746337890625MB)free=19523568(18.619125366210938MB)11.337498256138392%used670internedStringsoccupying43720bytes.
查看堆内存(histogram)中的对象数量及大小。执行命令:jmap-histo3331
numbytesclassname编号个数字节类名----------------------------------------------1:71322080[I2:5603722368methodKlass3:5603641944constMethodKlass4:34022544352:371437208constantPoolKlass6:336270624constantPoolCacheKlass7:371253816instanceKlassKlass
将内存使用的详细情况输出到文件,执行命令:jmap-dump:format=b,file=heapDump6900
然后用jhat命令可以参看jhat-port5000heapDump在浏览器中访问:http://localhost:5000/查看详细信息
总结1.如果程序内存不足或者频繁GC,很有可能存在内存泄露情况,这时候就要借助Java堆Dump查看对象的情况。2.要制作堆Dump可以直接使用jvm自带的jmap命令3.可以先使用jmap-heap命令查看堆的使用情况,看一下各个堆空间的占用情况。4.使用jmap-histo:[live]查看堆内存中的对象的情况。如果有大量对象在持续被引用,并没有被释放掉,那就产生了内存泄露,就要结合代码,把不用的对象释放掉。5.也可以使用jmap-dump:format=b,file=命令将堆信息保存到一个文件中,再借助jhat命令查看详细内容6.在内存出现泄露、溢出或者其它前提条件下,建议多dump几次内存,把内存文件进行编号归档,便于后续内存整理分析。
出现问题:Errorattachingtoprocess::Can’tattachtotheprocess在ubuntu中第一次使用jmap会报错:Errorattachingtoprocess::Can'tattachtotheprocess,这是oracla文档中提到的一个bug::
echo0|sudotee/proc/sys/kernel/yama/ptrace_scope该方法在下次重启前有效。
永久有效方法sudovi/etc//10-编辑下面这行:_scope=1修改为:_scope=0重启系统,使修改生效。赵小胖个人博客