范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

JVM性能调优监控工具jpsjstackjmapjhatjstathprof详解

  现实企业级Java应用开发、维护中,有时候我们会碰到下面这些问题:
  OutOfMemoryError,内存不足  内存泄露  线程死锁  锁争用(Lock Contention)  Java进程消耗CPU过高  ......
  这些问题在日常开发、维护中可能被很多人忽视(比如有的人遇到上面的问题只是重启服务器或者调大内存,而不会深究问题根源),但能够理解并解决这些问题是Java程序员进阶的必备要求。
  本文将对一些常用的JVM性能调优监控工具进行介绍,希望能起抛砖引玉之用。
  一、 jps(Java Virtual Machine Process Status Tool) :基础工具
  jps主要用来输出JVM中运行的进程状态信息。语法格式如下:
  jps [options] [hostid]
  如果不指定hostid就默认为当前主机或服务器。
  命令行参数选项说明如下:
  -q 不输出类名、Jar名和传入main方法的参数  -m 输出传入main方法的参数  -l 输出main类或Jar的全限名  -v 输出传入JVM的参数
  比如下面:
  root@ubuntu:/# jps -m -l 2458 org.artifactory.standalone.main.Main /usr/local/artifactory-2.2.5/etc/jetty.xml 29920 com.sun.tools.hat.Main -port 9998 /tmp/dump.dat 3149 org.apache.catalina.startup.Bootstrap start 30972 sun.tools.jps.Jps -m -l 8247 org.apache.catalina.startup.Bootstrap start 25687 com.sun.tools.hat.Main -port 9999 dump.dat 21711 mrf-center.jar
  二、 jstack
  jstack主要用来查看某个Java进程内的线程堆栈信息。语法格式如下:
  jstack [option] pid jstack [option] executable core jstack [option] [server-id@]remote-hostname-or-ip
  命令行参数选项说明如下:
  -l long listings,会打印出额外的锁信息,在发生死锁时可以用jstack -l pid来观察锁持有情况-m mixed mode,不仅会输出Java堆栈信息,还会输出C/C++堆栈信息(比如Native方法)
  jstack可以定位到线程堆栈,根据堆栈信息我们可以定位到具体代码,所以它在JVM性能调优中使用得非常多。
  下面我们来一个实例找出某个Java进程中最耗费CPU的Java线程并定位堆栈信息,用到的命令有ps、top、printf、jstack、grep。
  第一步先找出Java进程ID,我部署在服务器上的Java应用名称为mrf-center:
  root@ubuntu:/# ps -ef | grep mrf-center | grep -v grep root     21711     1  1 14:47 pts/3    00:02:10 java -jar mrf-center.jar
  得到进程ID为21711,第二步找出该进程内最耗费CPU的线程,可以使用ps -Lfp pid或者ps -mp pid -o THREAD, tid, time或者top -Hp pid,我这里用第三个,输出如下:
  TIME列就是各个Java线程耗费的CPU时间,CPU时间最长的是线程ID为21742的线程,用
  printf "%x " 21742
  得到21742的十六进制值为54ee,下面会用到。
  OK,下一步终于轮到jstack上场了,它用来输出进程21711的堆栈信息,然后根据线程ID的十六进制值grep,如下:
  root@ubuntu:/# jstack 21711 | grep 54ee "PollIntervalRetrySchedulerThread" prio=10 tid=0x00007f950043e000 nid=0x54ee in Object.wait() [0x00007f94c6eda000]
  可以看到CPU消耗在PollIntervalRetrySchedulerThread这个类的Object.wait(),我找了下我的代码,定位到下面的代码:
  // Idle wait getLog().info("Thread [" + getName() + "] is idle waiting..."); schedulerThreadState = PollTaskSchedulerThreadState.IdleWaiting; long now = System.currentTimeMillis(); long waitTime = now + getIdleWaitTime(); long timeUntilContinue = waitTime - now; synchronized(sigLock) {try {     if(!halted.get()) {     sigLock.wait(timeUntilContinue);     }     } catch (InterruptedException ignore) {     } }
  它是轮询任务的空闲等待代码,上面的sigLock.wait(timeUntilContinue)就对应了前面的Object.wait()。
  三、 jmap(Memory Map)和 jhat(Java Heap Analysis Tool):
  jmap导出堆内存,然后使用jhat来进行分析,jmap语法格式如下:
  jmap [option] pid jmap [option] executable core jmap [option] [server-id@]remote-hostname-or-ip
  如果运行在64位JVM上,可能需要指定-J-d64命令选项参数。
  jmap -permstat pid
  打印进程的类加载器和类加载器加载的持久代对象信息,输出:类加载器名称、对象是否存活(不可靠)、对象地址、父类加载器、已加载的类大小等信息,如下图:
  使用jmap -heap pid查看进程堆内存使用情况,包括使用的GC算法、堆配置参数和各代中堆内存使用情况。比如下面的例子:
  root@ubuntu:/# jmap -heap 21711 Attaching to process ID 21711, please wait... Debugger attached successfully. Server compiler detected. JVM version is 20.10-b01  using thread-local object allocation. Parallel GC with 4 thread(s)  Heap Configuration: MinHeapFreeRatio = 40    MaxHeapFreeRatio = 70    MaxHeapSize      = 2067791872 (1972.0MB) NewSize          = 1310720 (1.25MB) MaxNewSize       = 17592186044415 MB OldSize          = 5439488 (5.1875MB) NewRatio         = 2    SurvivorRatio    = 8    PermSize         = 21757952 (20.75MB) MaxPermSize      = 85983232 (82.0MB)  Heap Usage: PS Young Generation Eden Space:    capacity = 6422528 (6.125MB)    used     = 5445552 (5.1932830810546875MB)    free     = 976976 (0.9317169189453125MB)    84.78829520089286% used From Space:    capacity = 131072 (0.125MB)    used     = 98304 (0.09375MB)    free     = 32768 (0.03125MB)    75.0% used To Space:    capacity = 131072 (0.125MB)    used     = 0 (0.0MB)    free     = 131072 (0.125MB)    0.0% used PS Old Generation    capacity = 35258368 (33.625MB)    used     = 4119544 (3.9287033081054688MB)    free     = 31138824 (29.69629669189453MB)    11.683876009235595% used PS Perm Generation    capacity = 52428800 (50.0MB)    used     = 26075168 (24.867218017578125MB)    free     = 26353632 (25.132781982421875MB)    49.73443603515625% used    ....
  使用jmap -histo[:live] pid查看堆内存中的对象数目、大小统计直方图,如果带上live则只统计活对象,如下:
  root@ubuntu:/# jmap -histo:live 21711 | more num     #instances         #bytes  class name----------------------------------------------    1:         38445        5597736      2:         38445        5237288      3:          3500        3749504      4:         60858        3242600      5:          3500        2715264      6:          2796        2131424      7:          5543        1317400  [I    8:         13714        1010768  [C    9:          4752        1003344  [B   10:          1225         639656     11:         14194         454208  java.lang.String   12:          3809         396136  java.lang.Class   13:          4979         311952  [S   14:          5598         287064  [[I   15:          3028         266464  java.lang.reflect.Method   16:           280         163520     17:          4355         139360  java.util.HashMap$Entry   18:          1869         138568  [Ljava.util.HashMap$Entry;   19:          2443          97720  java.util.LinkedHashMap$Entry   20:          2072          82880  java.lang.ref.SoftReference   21:          1807          71528  [Ljava.lang.Object;   22:          2206          70592  java.lang.ref.WeakReference   23:           934          52304  java.util.LinkedHashMap   24:           871          48776  java.beans.MethodDescriptor   25:          1442          46144  java.util.concurrent.ConcurrentHashMap$HashEntry   26:           804          38592  java.util.HashMap   27:           948          37920  java.util.concurrent.ConcurrentHashMap$Segment   28:          1621          35696  [Ljava.lang.Class;   29:          1313          34880  [Ljava.lang.String;   30:          1396          33504  java.util.LinkedList$Entry   31:           462          33264  java.lang.reflect.Field   32:          1024          32768  java.util.Hashtable$Entry   33:           948          31440  [Ljava.util.concurrent.ConcurrentHashMap$HashEntry;
  class name是对象类型,说明如下:
  B  byte C  char D  double F  float I  int J  long Z  boolean [  数组,如[I表示int[] [L+类名 其他对象
  还有一个很常用的情况是:用jmap把进程内存使用情况dump到文件中,再用jhat分析查看。jmap进行dump命令格式如下:
  jmap -dump:format=b,file=dumpFileName pid
  我一样地对上面进程ID为21711进行Dump:
  root@ubuntu:/# jmap -dump:format=b,file=/tmp/dump.dat 21711 Dumping heap to /tmp/dump.dat ... Heap dump file created
  dump出来的文件可以用MAT、VisualVM等工具查看,这里用jhat查看:
  root@ubuntu:/# jhat -port 9998 /tmp/dump.dat Reading from /tmp/dump.dat... Dump file created Tue Jan 28 17:46:14 CST 2014Snapshot read, resolving... Resolving 132207 objects... Chasing references, expect 26 dots.......................... Eliminating duplicate references.......................... Snapshot resolved. Started HTTP server on port 9998Server is ready.
  注意如果Dump文件太大,可能需要加上-J-Xmx512m这种参数指定最大堆内存,即jhat -J-Xmx512m -port 9998 /tmp/dump.dat。然后就可以在浏览器中输入主机地址:9998查看了:
  上面红线框出来的部分大家可以自己去摸索下,最后一项支持OQL(对象查询语言)。
  四、jstat(JVM统计监测工具):
  看看各个区内存和GC的情况
  语法格式如下:
  jstat [ generalOption | outputOptions vmid [interval[s|ms] [count]] ]
  vmid是Java虚拟机ID,在Linux/Unix系统上一般就是进程ID。interval是采样时间间隔。count是采样数目。比如下面输出的是GC信息,采样时间间隔为250ms,采样数为4:
  root@ubuntu:/# jstat -gc 21711 250 4 S0C    S1C    S0U    S1U      EC       EU        OC         OU       PC     PU    YGC     YGCT    FGC    FGCT     GCT 192.0  192.0   64.0   0.0    6144.0   1854.9   32000.0     4111.6   55296.0 25472.7    702    0.431   3      0.218    0.649 192.0  192.0   64.0   0.0    6144.0   1972.2   32000.0     4111.6   55296.0 25472.7    702    0.431   3      0.218    0.649 192.0  192.0   64.0   0.0    6144.0   1972.2   32000.0     4111.6   55296.0 25472.7    702    0.431   3      0.218    0.649 192.0  192.0   64.0   0.0    6144.0   2109.7   32000.0     4111.6   55296.0 25472.7    702    0.431   3      0.218    0.649
  要明白上面各列的意义,先看JVM堆内存布局:
  可以看出:
  堆内存 = 年轻代 + 年老代 + 永久代 年轻代 = Eden区 + 两个Survivor区(From和To)
  现在来解释各列含义:
  S0C、S1C、S0U、S1U:Survivor 0/1区容量(Capacity)和使用量(Used) EC、EU:Eden区容量和使用量 OC、OU:年老代容量和使用量 PC、PU:永久代容量和使用量 YGC、YGT:年轻代GC次数和GC耗时 FGC、FGCT:Full GC次数和Full GC耗时 GCT:GC总耗时
  五、hprof(Heap/CPU Profiling Tool):
  hprof能够展现CPU使用率,统计堆内存使用情况。
  语法格式如下:
  java -agentlib:hprof[=options] ToBeProfiledClass java -Xrunprof[:options] ToBeProfiledClass javac -J-agentlib:hprof[=options] ToBeProfiledClass
  完整的命令选项如下:
  Option Name and Value  Description                    Default ---------------------  -----------                    ------- heap=dump|sites|all    heap profiling                 all cpu=samples|times|old  CPU usage                      off monitor=y|n            monitor contention             n format=a|b             text(txt) or binary output     a file=            write data to file             java.hprof[.txt] net=:      send data over a socket        off depth=           stack trace depth              4 interval=          sample interval in ms          10 cutoff=         output cutoff point            0.0001 lineno=y|n             line number in traces?         y thread=y|n             thread in traces?              n doe=y|n                dump on exit?                  y msa=y|n                Solaris micro state accounting n force=y|n              force output to          y verbose=y|n            print messages about dumps     y
  来几个官方指南上的实例。
  CPU Usage Sampling Profiling(cpu=samples)的例子:
  java -agentlib:hprof=cpu=samples,interval=20,depth=3 Hello
  上面每隔20毫秒采样CPU消耗信息,堆栈深度为3,生成的profile文件名称是java.hprof.txt,在当前目录。
  CPU Usage Times Profiling(cpu=times)的例子,它相对于CPU Usage Sampling Profile能够获得更加细粒度的CPU消耗信息,能够细到每个方法调用的开始和结束,它的实现使用了字节码注入技术(BCI):
  javac -J-agentlib:hprof=cpu=times Hello.java
  Heap Allocation Profiling(heap=sites)的例子:
  javac -J-agentlib:hprof=heap=sites Hello.java
  Heap Dump(heap=dump)的例子,它比上面的Heap Allocation Profiling能生成更详细的Heap Dump信息:
  javac -J-agentlib:hprof=heap=dump Hello.java
  虽然在JVM启动参数中加入-Xrunprof:heap=sites参数可以生成CPU/Heap Profile文件,但对JVM性能影响非常大,不建议在线上服务器环境使用
  本文来源:www.iteye.com/blog/josh-persistence-2161848

蔡文姬为什么这么恶心?这样的出装又有输出又恶心。王者荣耀中有个让人哭笑不得的英雄,那就是DJ蔡文姬莫属了。一首曲子弹到对面怀疑人生,一个2技能在敌人周围来回蹦个没完没了,害的别人技能都衔接不上好不容易刺客冲到射手边上,反手一个大经常拉伸的人,要想拉伸效果更好,这些知识一定要看看拉伸其实分为很多种类型,根据玩家的目标不同,拉伸可以分为运动前激活拉伸运动后放松拉伸柔韧性拉伸等等。而根据针对部位的不同,拉伸可以分为关节拉伸肌肉拉伸脊柱拉伸(也属于关节拉伸)等等LOL增加新功能,一键爆基地和叠满女神泪英雄联盟在S7赛季时,推出了训练模式,这个模式中允许玩家调整自己的等级和金钱,可以快速达到六神装和18级。对于那些热爱测试游戏数据的玩家而言,训练模式给予了他们巨大的便利。在过去几光剑是男人的浪漫细数DNF最帅的几把光剑还记得在DNF早期时候,鬼剑士的光剑推出过几把灯管,很长一段时间内都被玩家所追捧。当时在地下城战斗的时候,都有种在玩星球大战的感觉。现在游戏已经10年过去了,这些灯管有的已经绝版了继PDD之后,55开卢本伟也将复出直播?斗鱼官方言论露端倪在如今的直播局势里,可以说是一超多强的局面,超级主播旭旭宝宝一家独大,并伴随着有多个过百万人气的大主播存在,然而这种局面在今晚就即将结束,因为玩家们熟悉的骚猪PDD即将回归,在斗鱼荒野乱斗游戏模式抢先看,冒险之路嗨不停!相信许多小伙伴最近也知道了荒野乱斗预注册开启的消息,预注册都来了,正式上线还会远吗?作为一款即时对战游戏,荒野乱斗有着多种趣味模式,每种模式在节奏快时间短的基础上,又都有着鲜明的玩半肉狄仁杰无敌?反手拿出这几个英雄,任何一个都能打自闭!狄仁杰是最特殊的一个射手,本身就是射手无疑的英雄缺被大家出成半肉装,在S14赛季中狄仁杰有一个令人闻风丧胆的外号真战士。狄仁杰本身就是一个非常全面的英雄,虽然狄仁杰的位移只有一厘米剑魔听说我的复活要没了!设计师是的,但你技能没CD了!自从羞男在S8上一手剑魔一拍四以后,剑魔这个英雄就彻底火了起来,各个段位的各种模式中都能看到他活跃的身影,这个英雄仿若一夜之间变成了一个信仰,玩剑魔的玩家没有一个怂的,哪怕不会玩哪Uzi的2800算什么?他比史上最低高出6倍多游戏马蹄铁原创Uzi和2800比赛伤害输出面板,是前几年开始职业赛上用来给出赛后点评用的。原本主要目的就是为了给评论席更多可以讨论的东西,以及用来记录一场比赛的大数据。但是自从某些王者不懂这些英雄的隐形属性,是要吃大亏的,老玩家都被打怕了相信绝大多数玩家都不喜欢看英雄技能的介绍,只要知道这个英雄怎么玩,怎么放技能就可以了。那就让小编为大家解读吧,然后我们一起上分上星上王者。首先我们看看庄周这个英雄,大家都知道他大招几款只能偷偷玩的沙雕游戏,看封面就知道是好东西!但凡是地球人,或多或少都知道一点电子游戏。随着时代进步,长辈逐渐意识到,游戏不再简单意味着不务正业。例如沙盒游戏Minecraft就被正式纳入多国多地的教育系统。然而绝大多数的父母
每日游讯使命召唤14加入6月会免君与彼女与彼女之恋登陆Steam夏洛克福尔摩斯第一章面向平台公布Frogwares日前公布了发布了夏洛克福尔摩斯第一章,该游戏将于2021年推出,登PlayStation5,XboxSeriesX,PlaySta每日游讯神界原罪2DLC免费Klei新作欺诈之地抢先体验神界原罪2免费新DLC上线今日(6月15日)拉瑞安工作室推出了神界原罪2新DLC绿维珑四神器,玩家将面对新的敌人,发掘新的宝藏,还有新的学识。该DLC完全免费,请玩家尽情享用。绿维每日游讯地平线黎明时分涨至193求生之路团队新作嗜血回归地平线黎明时分Steam涨价至193元更新除了国区,Steam多国地平线黎明时分的售价均上涨,其中土耳其俄罗斯阿根廷等地的涨价非常夸张,成倍地上涨,涨价幅度达34倍,可以说是相当夸冒险岛宠物相关知识科普本篇文章会和大家介绍目前宠物相关的小知识,包括常见的宠物类型宠物技能宠物装备宠物装备打造以及宠物强化。帮助读者朋友们看完以后对宠物及其相关选择有一个大致的认知。本文将会以下面的目录史蒂芬霍金去世启明星滑落,享年76岁2018年3月14日,据英国天空新闻等多家媒体,史蒂芬霍金去世,享年76岁。今天下课看到知乎,朋友圈,QQ空间集体悼念霍金老爷子,我才知道他离世的噩耗,我没有跟风朋友圈悼念,但我内辟谣杨建平声明喷水只是表演秀,选手并非日本人前几日,微信朋友圈被杨建平KO日本人视频刷爆,杨建平,1988年11月出生,现年近30岁,国家级运动健将,曾获世界自由搏击锦标赛65公斤级冠军,中国综合搏击65公斤级金腰带持有者。每日游讯英雄传说创之轨迹新情报万代手游罪纹传说国行Switch更新微信朋友间能互加NS好友近日腾讯国行NintendoSwitch发布了10。1。0系统更新,加入新的好友功能,方便微信朋友之间互相添加NS好友。此外,腾讯还在为CCTV16将开播,成全球首个24小时上星播出的4K超高清体育频道10月11日,中央广播电视总台奥林匹克频道开播上线专家座谈会在北京举行。根据央视新闻,该频道将是全球首个24小时上星播出的4K超高清体育频道,包含央视奥林匹克电视频道和数字平台。其北京幼儿体育协会成立,计划培育扶持一批幼儿体育龙头企业北京时间10月8日,据新华社报道,北京幼儿体育协会正式揭牌成立。这标志着在双减政策背景下,北京在开展幼儿体育活动实施健康儿童行动计划方面迈出的新步伐。北京大学妇女体育研究中心主任教那些能让我玩1000小时以上的游戏有哪些游戏你玩了超过一千个小时从90年代初开始接触电子游戏,到1996年第一次接触电脑游戏,一直到现在。玩过的游戏真的数不胜数,不过真正让我玩了1000小时以上的游戏,我思来想去,自由度不弱GTA5,这款Steam游戏老外含泪玩上千小时GTA5是Steam上的一代神作,相信大家都或多或少有听说过这款游戏的名字。GTA5之所以能在全球热销,卖出1。35亿份,很大程度上是因为游戏塑造出了一个极为自由和开放的世界,在游