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

带着8个问题5分钟教你学会Arthas诊断工具

  Arthas  是Alibaba开源的Java诊断工具,深受开发者喜爱。
  当你遇到以下类似问题而束手无策时,Arthas 可以帮助你解决: 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?  我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?  遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?  线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!  是否有一个全局视角来查看系统的运行状况?  有什么办法可以监控到JVM的实时运行状态?  怎么快速定位应用的热点,生成火焰图?  怎样直接从JVM内查找某个类的实例?
  这 8 个问题,Arthas 官方文档(https://arthas.aliyun.com/doc )中并没有给出答案或标准的解决方案。
  坑爹啊
  这不是管杀不管埋吗!! 准备先给出我的测试代码package com.admin.study;  import com.alibaba.fastjson.JSON; import lombok.AccessLevel; import lombok.Getter; import lombok.Setter; import lombok.ToString; import lombok.experimental.FieldDefaults;  import java.util.List; import java.util.concurrent.TimeUnit;  public class ArthasDemo {     public static void main(String[] args) {         String s = "[{"name":"zhangsan","age":"10","telephone":"123456","interests":["sing","dance","rap"]}, " +                 "{"name":"lisi","age":"20","telephone":"123457","interests":["sing","swim"]}, " +                 "{"name":"wangwu","age":"30","telephone":"123458","interests":["sing","program"]}]";         //模拟一遍遍的调用方法的过程         for (; ; ) {             System.out.println(new ArthasDemo().convert(s));             try {                 TimeUnit.SECONDS.sleep(10);             } catch (InterruptedException e) {                 e.printStackTrace();             }         }     }      private List convert(String s) {         return JSON.parseArray(s, People.class);     }       @Getter     @Setter     @ToString     @FieldDefaults(level = AccessLevel.PRIVATE)     private static class People {         /**          * 姓名          */         String name;         /**          * 年龄          */         String age;         /**          * 电话          */         String telephone;         /**          * 兴趣列表          */         List interests;     } } 以下是控制台正常打印的结果/Library/Java/JavaVirtualMachines/jdk1.8.0_192.jdk/Contents/Home/bin/java ... [ArthasDemo.People(name=zhangsan, age=10, telephone=123456, interests=[sing, dance, rap]), ArthasDemo.People(name=lisi, age=20, telephone=123457, interests=[sing, swim]), ArthasDemo.People(name=wangwu, age=30, telephone=123458, interests=[sing, program])] [ArthasDemo.People(name=zhangsan, age=10, telephone=123456, interests=[sing, dance, rap]), ArthasDemo.People(name=lisi, age=20, telephone=123457, interests=[sing, swim]), ArthasDemo.People(name=wangwu, age=30, telephone=123458, interests=[sing, program])]下载并运行 Arthas
  按照下图中的步骤,选择一个 Java 进程进行 attach。
  下载并运行Arthas 访问 WebConsole
  attach 成功后可以打开谷歌浏览器输入http://127.0.0.1:3658/  打开 WebConsole
  (吐槽一句 Mac OS 的 Safari 浏览器不支持) 使用 WebConsole 最方便的是你可以打开多个标签页同时操作
  问题 1:这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
  这个问题我经常在处理各种「依赖冲突」 的时候遇到,有一些类的完全名称是一模一样,通过常规的办法无法解决类具体从哪个 jar 包加载。
  别急,看我下面的解决办法。 sc
  通过 sc  命令 模糊查看当前 JVM 中是否加载了包含关键字的类,以及获取其完全名称。 注意使用 sc -d  命令,获取 classLoaderHash,这个值在后面需要用到。
  sc -d *ArthasDemo*
  sc-d命令 classloader
  通过 classloader  查看 class 文件来自哪个 jar 包 使用 cls  命令可以清空命令行,这个简单的命令官方文档居然找不到…
  注意 classloader -c  后面的值填上面第一步中获取到的 Hash 值,class 文件路径使用"/"分割,且必须以.class 结尾。
  [arthas@3633]$ classloader -c 18b4aac2 -r com/admin/study/ArthasDemo.class file:/Users/admin/code/concurrentbook/target/classes/com/shockang/study/ArthasDemo.class Affect(row-cnt:1) cost in 0 ms.
  上面是显示 class 文件路径的,如果 class 文件来自 jar 包,可以显示 jar 包路径,例如官方文档给的例子: $ classloader -c 1b6d3586 -r java/lang/String.class jar:file:/Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/jre/lib/rt.jar!/java/lang/String.class问题 2:我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
  推荐使用 watch  和 tt  命令,非常好用。
  这两个命令都是用来查看方法调用过程的,不同的是 watch  命令是调用一次打印一次方法的调用情况,而 tt  命令可以先生成一个不断增加的调用列表,然后指定其中某一项进行观测。 使用  watch  命令查看方法调用情况。我们要查看 ArthasDemo 这个类里面的 convert 方法调用情况。
  watch命令 watch com.shockang.study.ArthasDemo convert "{params,target,returnObj}" -f -x 4
  watch  后面跟上完全类名和方法名,以及一个 OGNL 的表达式,-f 表示不论正常返回还是异常返回都进行观察,-x 表示输出结果的属性遍历深度,默认为 1, 建议无脑写 4 就行,这是笔者经验来看最大的遍历深度,再大就不支持了
  使用  tt  命令来观测方法调用情况,tt  命令可以查看「多次调用」 并选择其中一个进行观测,但是如果输出结果是多层嵌套就没办法看了,而 watch  可以查看「多层嵌套」 的结果。 使用 tt -t 记录下当前方法的每次调用环境现场
  tt -t命令 tt -t com.shockang.study.ArthasDemo convert
  TIMESTAMP表示方法调用发生的时间,COST 表示调用耗时(ms),IS-RET表示是否正常返回,IS-EXP 表示是否异常返回,OBJECT 表示对象的 HASH 值 对于具体一个时间片的信息而言,你可以通过 -i 参数后边跟着对应的 INDEX 编号查看到他的详细信息
  tt-i命令 图中之所以可以打印兴趣列表,是调用了其 toString 方法,如果没有重写 java.lang.Object 类的 toString 方法,只会看到 hash 值。
  如何判断代码是否已经提交?
  通过 jad --source-only  可以查看源代码。 [arthas@3633]$ jad --source-only com.admin.study.ArthasDemo        /*         * Decompiled with CFR.         */        package com.admin.study;         import com.alibaba.fastjson.JSON;        import java.util.List;        import java.util.concurrent.TimeUnit;         public class ArthasDemo {            public static void main(String[] args) { /*15*/         String s = "[{"name":"zhangsan","age":"10","telephone":"123456","interests":["sing","dance","rap"]}, {"name":"lisi","age":"20 ","telephone":"123457","interests":["sing","swim"]}, {"name":"wangwu","age":"30","telephone":"123458","interests":["sing","program"]}]";                while (true) { /*20*/             System.out.println(new ArthasDemo().convert(s));                    try { /*22*/                 TimeUnit.SECONDS.sleep(10L); /*25*/                 continue;                    }                    catch (InterruptedException e) { /*24*/                 e.printStackTrace();                        continue;                    }                    break;                }            }             private List convert(String s) { /*30*/         return JSON.parseArray(s, People.class);            }             private static class People {                private String name;                private String age;                private String telephone;                private List interests;                 private People() {                }                 public String toString() {                    return "ArthasDemo.People(name=" + this.getName() + ", age=" + this.getAge() + ", telephone=" + this.getTelephone() + ", interests=" + this.getIntere sts() + ")";                }                 public String getName() {                    return this.name;                }                 public void setName(String name) {                    this.name = name;                }                 public String getAge() {                    return this.age;                }                 public String getTelephone() {                    return this.telephone;                }                 public List getInterests() {                    return this.interests;                }                 public void setAge(String age) {                    this.age = age;                }                 public void setTelephone(String telephone) {                    this.telephone = telephone;                }                 public void setInterests(List interests) {                    this.interests = interests;                }            }        }  [arthas@3633]$问题 3:遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
  通过上面问题 2 的 watch  和 tt  命令可以查看方法调用情况。
  此外,可以通过 redefine  命令「热替换」 线上的代码,注意应用重启之后会失效,这在某些紧急情况下会有奇效。
  比如说我们修改一下方法体里面的代码,加了一行日志打印:     private List convert(String s) {         System.out.println(s);         return JSON.parseArray(s, People.class);     }
  这时我们就可以将新代码编译后的 class 文件热替换正在运行的 ArthasDemo 的代码。
  redefine命令
  热替换 JVM 内存中(方法区)加载的类
  从这张图可以明显的看出,明明源码中没有打印字符串 s 的逻辑,但是控制台还是打印了字符串,因为我们已经热替换了 JVM 内存中(方法区)加载的类。 问题 4:线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
  这个问题没有完美的解决办法
  参考一下问题 2 和问题 3的解决方案
  推荐使用 tt  命令并将命令行返回结果输出到一个文件中,后续可以选择异常的一行记录使用 tt -i  命令进行深入的分析。
  tee 指令会从标准输入设备读取数据,将其内容输出到标准输出设备,同时保存成文件。
  tee命令 tt -t com.admin.study.ArthasDemo convert | tee /Users/admin/Downloads/log
  此外还可以使用 monitor  命令统计方法调用成功失败情况。
  monitor命令 monitor -c 30 com.admin.study.ArthasDemo convert | tee /Users/admin/Downloads/log1-c 后面接统计周期,默认值为120秒
  问题 5:是否有一个全局视角来查看系统的运行状况?
  使用 dashboard  命令可以查看当前系统的实时数据面板, 当运行在Ali-tomcat时,会显示当前tomcat的实时信息,如HTTP请求的qps, rt, 错误数, 线程池信息等等。
  dashboard实时数据面板
  从图中可以看到线程情况,内存使用情况,系统参数等。 问题 6:有什么办法可以监控到JVM的实时运行状态?
  使用 jvm  命令可以查看 JVM 的实时运行状态。
  JVM 的实时运行状态 问题 7:怎么快速定位应用的热点,生成火焰图?
  profiler  命令支持生成应用热点的火焰图。本质上是通过不断的采样,然后把收集到的采样结果生成火焰图。 默认情况下,生成的是 cpu 的火焰图,即 event 是 cpu,可以用--event 参数来指定。注意不同系统支持的 event 不同
  默认情况下,arthas使用3658端口,则可以打开:http://localhost:3658/arthas-output/  查看到arthas-output目录下面的profiler结果:
  profiler目录
  选择一项点击
  profiler结果图 问题 8:怎样直接从JVM内查找某个类的实例?
  使用 vmtool  可以达成目的 这个功能是 Arthas 3.5.1 新增的。可以参考官方文档 https://arthas.aliyun.com/doc/vmtool.html#id1
  $ vmtool --action getInstances --className java.lang.String --limit 10 @String[][     @String[com/taobao/arthas/core/shell/session/Session],     @String[com.taobao.arthas.core.shell.session.Session],     @String[com/taobao/arthas/core/shell/session/Session],     @String[com/taobao/arthas/core/shell/session/Session],     @String[com/taobao/arthas/core/shell/session/Session.class],     @String[com/taobao/arthas/core/shell/session/Session.class],     @String[com/taobao/arthas/core/shell/session/Session.class],     @String[com/],     @String[java/util/concurrent/ConcurrentHashMap$ValueIterator],     @String[java/util/concurrent/locks/LockSupport], ]
  通过 --limit 参数,可以限制返回值数量,避免获取超大数据时对JVM造成压力。默认值是10。
  如果想精确的定位到具体的类实例,可以通过指定 classloader name 或者 classloader hash,如下所示: vmtool --action getInstances --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader --className org.springframework.context.ApplicationContextvmtool --action getInstances -c 19469ea2 --className org.springframework.context.ApplicationContext获取 classloader hash 的方法请参考上面的问题 1
  vmtool 还有个不错的功能,可以「强制进行GC」 ,这在某些生产环境内存紧张的情况下有奇效。 vmtool --action forceGc

本田奥德赛试驾2。0L锐尊享版,配7座侧滑门实力如何?作为一款MPV车型,奥德赛销量虽然不及别克GL8,但在同级别车中也是翘楚,从7月份公布的销量来看,卖出了5862台。对于家庭用户来说,奥德赛外观沉稳大气,空间满足7座没有问题,算是试驾迈巴赫S级,配3。0T双涡轮空气悬架,卖146。8万贵吗?每个人的梦想不同,作为一个专业车评人,对于我而言想在未来的人生中开上迈巴赫S级。虽然目前没有钱购买,但我自己有一定的渠道,最近试驾了2021款S4804MATIC,目前在售版本只有风神奕炫MAX紧凑型定位车长近4米8,标配1。5T引擎实力如何?对于年轻人来讲,买车肯定以家用舒适为主,如果能在此基础上具备一定运动感就再好不过了,如果在此基础上能够具备同级别比较好的空间,能够抵挡诱惑的就比较少了。现在很多国产新车型都是往这几当红时文如有不幸,我愿捐出遗体作者王永波如有不幸,我愿捐出遗体作者江苏淮安王永波编审天美五星如有不幸我愿捐出遗体供攻克病毒研究这,就是在冠疫肆虐在与死神短兵相接的搏杀中武汉天佑医院小护士李慧留下掷地有声的铿锵誓言但李慧是当红小小说有情没情租个女友过年作者王永波原创首发有情没情租个女友过年(小小说)作者江苏淮安王永波编辑天美五星现在社会真是太疯狂了。租妻租女友这样的词眼竟然在网络上堂而皇之地出现。要过年了,这样的词眼出现的频率更高。要不是我亲眼所哈弗H9起售20。98万,标配2。0T引擎等不到坦克300就看它!对于国内消费者来讲,硬派越野SUV越来越多,比如说目前比较火爆的坦克300。但我们也不能忘了一些原有的真香车型,就比如说长城哈弗H9。作为一款中大型硬派越野SUV,目前2020款车颜值高配置全有品质,年轻人的摩登座驾是何模样?KiWiEV看我!对老一辈而言,汽车也许就是沙发4个轮子但对年轻一代来说,汽车是提升生活品质的关键消费品。为此,年轻人对车辆的用车品质也有一定要求,即便是微型电动车,年轻人也希望其具有较高的用车品质C实战050C调用C动态链接库及类库详解动态链接库动态链接库全称DynamicLinkLibrary(简称DLL),通常是由一组实现某种特定功能的函数集合。它包含了该功能的具体实现方法和资源,通过编译生成一个后缀为DLL真快乐APP改版试运营启动乐购新升级开启品质消费时代10月21日,以乐购新升级为主题的真快乐APP改版试运营发布会在京召开。本次发布会上,真快乐APP改版试运营,重点打造购乐两大版块。中国商业联合会副会长张丽君,中国商业联合会副秘书新年吃火锅庆团圆,帅锅聚齐来拜年过年啦!在传统的中国年里,全家在一起吃顿年夜饭成为了庆团圆的一种标志,在餐桌上各种美味佳肴数不胜数,火锅自然也被列入其中,深得人们的宠爱。大家围坐在一起,吃着热气腾腾的火锅,那气氛郑州雁鸣湖镇开展绿城妈妈巧手编织快乐相伴活动为丰富社区女性的业余生活,增强居民之间的互动,培养他们的兴趣爱好和提高他们的动手能力,3月16日下午,在中牟县妇联的指导下,恩夕社工在雁鸣湖镇朱固社区组织开展绿城妈妈巧手编织快乐相
曝2K分辨率国产屏幕华为Mate50,Mate40沦为弃机,彻底感人价来袭曝光新一代旗舰级别华为Mate50Pro高配置版本新机将会带来更大的突破,曝光新一代旗舰级别华为Mate50Pro高配置版本新机首次采用了一块支持2K分辨率的国产屏幕,曝光新一代旗诺基亚新5330渲染图面对苹果扮猪吃老虎,天玑90002亿液态相机诺基亚手机的众多机型当中,消费者对功能机的印象非常深,尤其是诺基亚手机的质量可靠,并且耐摔可以砸核桃等等使用体验也非常优秀。但是随着科技的进步,诺基亚功能机已经无法满足消费者的需求华为的这款5G手机,目前性比价很高,可惜被大家忽略了欢迎回家!请用你发财的手给小编点个关注点个赞,感谢大家支持!大家也知道,华为被限制芯片后,发布的一部分手机不仅不支持5G,麒麟芯片也没法用了,现在华为的nova系列和mate系列P2022年亚马逊还能做吗?我是17年年底开始做亚马逊的,以一个过来人的身份建议小白还是慎入,除非你身边有已经再做亚马逊做的比较好的朋友我做亚马逊是在创业失败还在负债的情况下接触到亚马逊的,刚开始做的时候每天马云果然不简单,这是要二次创业?近年来,马云可以说是越来越低调了,究其原因可能还是因为去年马云的不当言论。最近,经过各大媒体的不懈努力,终于捕捉到了马云的踪迹。原来,马云自从离开阿里巴巴之后,并没有安心去过采菊东比特币首富李笑来,用10万枚比特币套现135亿,称比特币是割韭菜今年的比特币价格再次迎来疯涨,相比去年价格几乎翻了个翻,每枚价格在五万美元左右波动,远远超过了过去国内比特币狂潮时的价格。在那段比特币狂潮里,有一个谈及比特币便绕不过去的人李笑来。马云任正非马化腾曹德旺你认为哪个是中国最优秀的企业家?我认为任正非和曹德旺,这二位是为国家服务的,是中国最优秀的企业家。答这四位都优秀,马云和任正非更为突出。不靠地盘楼房矿产和拍买国有资产做大的我基本认可。肯定曹任两位企业家俗话说老百小米12渲染图出现了,k50系列处理器使用原则曝光?小米12的渲染图出现了,基本上和曝光的手机壳差不多,当然红米k50手机看起来也曝光了一些配置,简单看看这些新消息吧!小米12系列基本上确定使用竖向排列的摄像头设计思路,当然有一个大中科曙光基于国产芯片高端计算机研发及扩产项目可行性研究报告1项目概况当前我国采用进口处理器芯片的高端计算机占据国内市场90以上的份额。受信息产业安全供应链安全等多方面因素的影响,发展基于国产处理器的高端计算机的重要性日益凸显。目前,国产处储能特高压配电网等新型电力系统的投资机会新能源比例逐步提高最终成为主力能源,为电力系统各环节带来深刻变化,新能源具随机性波动性间歇性,需要建立具备高预测能力高调节能力高智能化水平的新型电力系统。围绕新型电力系统所面临的痛今年全球已进行了134次火箭发射,其中中国52次,美国48次1Meta计划花费4亿美元收购VR健身应用程序Supernatural,遭遇联邦贸易委员会的重新审查,狮评在改名之前,Meta一直收购VR领域相关公司扩充其内部VR研发能力。201