本文转自互联网,侵删

本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看

https://github.com/h2pl/Java-Tutorial

喜欢的话麻烦点下Star哈

文章将同步到我的个人博客:

http://www.how2playlife.com

本文是微信公众号【Java技术江湖】的《深入理解JVM虚拟机》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。

该系列博文会告诉你如何从入门到进阶,一步步地学习JVM基础知识,并上手进行JVM调优实战,JVM是每一个Java工程师必须要学习和理解的知识点,你必须要掌握其实现原理,才能更完整地了解整个Java技术体系,形成自己的知识框架。

为了更好地总结和检验你的学习成果,本系列文章也会提供每个知识点对应的面试题以及参考答案。

如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。

一、VisualVM是什么?

VisualVM是一款免费的JAVA虚拟机图形化监控分析工具。

    1.  拥有图形化的监控界面。2. 提供本地、远程的JVM监控分析功能。3. 是一款免费的JAVA工具。4. VisualVM拥有丰富的插件支持。
## 二、如何获取VisualVM?VisualVM官方网站:http://visualvm.java.net/

    VisualVM各版本下载页面: http://visualvm.java.net/releases.html

     下载VisualVM时也应该注意,不同的JDK版本对应不同版本的VisualVM,具体根据安装的JDK版本来下载第一的VisualVM。

三、获取那个版本?

       下载版本参考:Java虚拟机性能管理神器 - VisualVM(4) - JDK版本与VisualVM版本对应关系

备注:下列表中显示1.3.6版本只适合JDK7和JDK8,可是我用1.3.6版还是可以监控JDK1.6_45的版本。

四、VisualVM能做什么?

  1. 显示JAVA应用程序配置和运行时环境。
    显示JAVA应用程序JVM参数,系统属性,JVM的信息和运行环境。
  1. 显示本地和远程JAVA应用程序运行状态。
    可以连接到远程服务器上运行的JAVA应用程序,监控应用程序的运行状态。
  1. 监控应用程序的性能消耗。
    可以监控到应用程序热点方法的执行单次时间、总耗时、耗时占比。
  1. 显示应用程序内存分配,显示分析堆信息。
    显示应用程序在运行时的编译时间、加载时间、垃圾回收时间、内存区域的回收状态等。
  1. 监控应用程序线程状态和生命周期。
    监控应用程序线程的运行、休眠、等待、锁定状态。
  1. 显示、分析线程堆信息。
    显示线程当前运行状态和关联类信息。
  1. 支持第三方插件来分析JAVA应用程序。
    另外还提供更多更强大、方便的第三方插件。

监控远程主机上的JAVA应用程序

    使用VisualVM监控远程主机上JAVA应用程序时,需要开启远程主机上的远程监控访问,或者在远程JAVA应用程序启动时,开启远程监控选项,两种方法,选择其中一种就可以开启远程监控功能,配置完成后就可以在本地对远程主机上的JAVA应用程序进行监控。

1.远程服务器、应用程序配置1.1配合jstatd工具提供监控数据
1.1.1创建安全访问文件在JAVA_HOME/bin目录中,创建名称为jstatdAllPolicy文件(这个文件名称也可以顺便起,不过要与jstatd启动时指定名称相同),将以下内容拷贝到文件中。并保证文件的权限和用户都正确。

        grant codebase"file:${java.home}/../lib/tools.jar"{ permission java.security.AllPermission; };

1.1.2启动jstatd服务在JAVA_HOME/bin目录中,执行以下命令:

         ./jstatd -J-Djava.security.policy=jstatdAllPolicy-p 1099 -J-Djava.rmi.server.hostname=192.168.xxx.xxx

        jstatd命令描述以及参数说明:

           jstatd是一个基于RMI(Remove Method Invocation)的服务程序,它用于监控基于HotSpot的JVM中资源的创建及销毁,并且提供了一个远程接口允许远程的监控工具连接到本地的JVM执行命令。

        -J-Djava.security.policy=jstatdAllPolicy 指定安全策略文件名称

         -p 1099  指定启动端口

         -J-Djava.rmi.server.hostname=192.168.xxx.xxx  指定本机IP地址,在hosts文件配置不正常时使用,最好加上。

1.2JVM启动时配置远程监控选项在需要远程监控的JVM启动时,开启远程监控选项

        -Dcom.sun.management.jmxremote.port=1099-Dcom.sun.management.jmxremote.ssl=false-Dcom.sun.management.jmxremote.authenticate=false-Djava.rmi.server.hostname=192.168.xxx.xxx

2.本地VisualVM配置在本地VisualVM的应用程序窗口,右键单击【远程】》【添加远程主机】》【主机名】中输入远程主机的IP地址,点击【高级设置】输入远程主机开启的监控端口,点击【确定】完成配置。

        如果一切正常,就可以看到远程主机上的JAVA应用程序了。

排查JAVA应用程序内存泄漏

  1. 发现问题
    线上应用部署完成后,运行1~2天左右就会出现假死,或者某天早上8~10点高峰期间突然不处理数据了。由于在测试环境的压力测试没有做完全,也没有遇到相关问题。情况出现后对客户的使用造成很大影响,领导要求赶紧排查出问题原因!
  1. 排查原因
    排查原因前,与运维沟通,了解线上服务器的运行状态,通过ganglila观察网络、CPU、内存、磁盘的运行历史状态,发现程序故障前,都有一波很高的负载,排查线上日志,负载来源在8~9点平台接入数据量成倍增加,通过与产品和市场人员分析,此时段是用户集中上班、接入平台的高峰时段,访问日志也显示,业务场景正常,无网络攻击和安全问题。属于产品业务正常的场景。
        排除了网络安全因素后,就从程序的运行内部进行排查,首先想到的获取JVM的dmp文件。获取JVM的dmp文件有两中方式:

        1. JVM启动时增加两个参数,出现 OOME 时生成堆 dump: 

                -XX:+HeapDumpOnOutOfMemoryError

                生成堆文件地址:

                -XX:HeapDumpPath=/home/test/jvmlogs/ 

        2. 发现程序异常前通过执行指令,直接生成当前JVM的dmp文件,15434是指JVM的进程号

                jmap -dump:format=b,file=serviceDump.dat    15434 

        由于第一种方式是一种事后方式,需要等待当前JVM出现问题后才能生成dmp文件,实时性不高,第二种方式在执行时,JVM是暂停服务的,所以对线上的运行会产生影响。所以建议第一种方式。

  1. 解决方案
    获取到dmp文件后,就开始进行分析。将服务器上的dmp文件拷贝到本地,然后启动本地的VisualVM,点击菜单栏【文件】选项,装入dmp文件
        打开dmp文件后,查看类标签,就能看到占用内存的一个排行。

        然后通过检查中查找最大的对象,排查到具体线程和对象。

        上列中的com.ctfo.trackservice.handler.TrackHandleThread#4就是重点排查对象。

        通过代码的比对,在此线程中,有调用DAO接口,负责将数据存储到数据库中。而存储到数据库中时,由于存储速度较慢,导致此线程中的数据队列满了,数据积压,无法回收导致了队列锁定,结果就是程序假死,不处理数据。

        通过进一步分析,发现数据库存储时有瓶颈,虽然当前是批量提交,速度也不快。平均8000/秒的存储速度。而数据库有一个DG(备份)节点,采用的是同步备份方式,即主库事务要等DG的事务也完成后才能返回成功,这样就会因为网络因素、DG性能因素等原因导致性能下降。通过与DBA、产品、沟通,将同步备份改为异步备份,实时同步改为异步(异步可能会导致主备有10分钟以内的数据延迟)。速度达到30000/秒。问题解决。

        至此,通过VisualVM分析java程序内存泄漏到此结束。不过还有几个问题:1. 如果dmp文件较大,VisualVM分析时间可能很久;另外,VisualVM对堆的分析显示功能还不算全面。如果需要更全面的显示,就可以使用另外一个专业的dmp文件分析工具【Memory Analyzer (MAT)】,此工具可以作为eclipse的插件进行安装,也可以单独下载使用。如果有感兴趣的朋友,我个人建议还是单独下载使用。下载地址:http://www.eclipse.org/mat/   

查找JAVA应用程序耗时的方法函数

1.为什么要监控?JAVA程序在开发前,根据设计文档的性能需求,是要对程序的性能指标进行测试的。比如接口每秒响应次数要求1000次/秒,就需要平均每次请求处理的时间在1ms以内,如果需要满足这个指标,就需要在开发阶段对接口执行函数进行监控,也可以通过打印日志进行监控,从而统计对应的性能指标,然后可以根据性能指标的要求进行相应优化。

  1. 那些方法函数需要监控?
    根据具体业务的场景和需求,主要集中在IO通讯、文件读写、数据库操作、业务逻辑处理上,这些都是制约性能的重要因素,所以需要重点关注。
  1. 如何排查
    在研发环境,大部分会使用syso的方式或者日志方式打印性能损耗,如果代码没有加在运行时才想起来,或者想关注突然想起的函数,换做以前,是需要重启服务的,如果有VisualVM就可以直接查看耗时以及调用次数等情况。而不用打印、输出日志来查看性能损耗。
  1. 如何处理
    对于性能损耗的函数,根据业务逻辑可以进行相应的优化,例如字符串处理、文件读写方式、SQL语句优化、多线程处理等等方式。
       由于性能优化涉及的内容很多,这里就不深入了。主要是告诉大家通过VisualVM来排查问题的具体位置。

排查JAVA应用程序线程锁

  1. JAVA应用程序线程锁原因
    JAVA线程锁的例子和原因网上一大堆,我也不在这里深入说明,这里主要是否讲如何使用VisualVM进行排查。至于例子可以看这里:http://blog.csdn.net/fengzhe0411/article/details/6953370

这个例子比较极端,一般情况下,出现锁竞争激烈是比较常见的。

  1. 排查JAVA应用程序线程锁
    启动 VisualVM,在应用程序窗口,选择对应的JAVA应用,在详情窗口》线程标签(勾选线程可视化),查看线程生命周期状态,主要留意线程生命周期中红色部分。

(1)绿色:代表运行状态。一般属于正常情况。如果是多线程环境,生产者消费者模式下,消费者一直处于运行状态,说明消费者处理性能低,跟不上生产者的节奏,需要优化对应的代码,如果不处理,就可能导致消费者队列阻塞的现象。对应线程的【RUNNABLE】状态。

(2)蓝色:代表线程休眠。线程中调用Thread.sleep()函数的线程状态时,就是蓝色。对应线程的【TIMED_WAITING】状态。

(3)黄色:代表线程等待。调用线程的wait()函数就会出现黄色状态。对应线程的【WAITING】状态。

(4)红色:代码线程锁定。对应线程的【BLOCKED】状态。

  1. 分析解决JAVA应用程序线程锁
    发生线程锁的原因有很多,我所遇到比较多的情况是多线程同时访问同一资源,且此资源使用synchronized关键字,导致一个线程要等另外一个线程使用完资源后才能运行。例如再没有连接池的情况下,同时访问数据库接口。这种情况会导致性能的极具下降,解决的方案是增加连接池,或者修改访问方式。或者将资源粒度细化,类似ConCurrentHashMap中的处理方式,将资源分为多个更小粒度的资源,在更小粒度资源上来处理锁,就可以解决资源竞争激烈的问题。]

参考文章

https://blog.csdn.net/android_hl/article/details/53228348

java visualvm远程监控_深入理解JVM虚拟机12:JVM性能管理神器VisualVM介绍与实战相关推荐

  1. java visualvm远程监控_如何监控和诊断堆外内存使用

    如何监控和诊断堆外内存使用 可以使用综合性的图形化工具,如 JConsole.VisualVM ,这些工具比较直观,直接连接到 Java 进程,图形化界面. 可以使用命令工具进行查询,如 jstat ...

  2. visualvm远程监控jvm_别再说你不会 JVM 性能监控和调优了,看完这篇再发言

    常用工具 常用工具主要有 JDK 自带工具与 Arthas 这两种工具. JDK 自带工具 jps 虚拟机进程状况工具 用于查看虚拟机进程状况的工具 命令示例 $ jps15236 Jps14966 ...

  3. java逻辑第九章_深入理解jvm-(第九章)类加载及执行子系统的案例与实战

    转载自:http://blog.csdn.net/coslay/article/details/49564789 概述 在Class文件格式与执行引擎这部分中,用户的程序能直接影响的内容并不太多, C ...

  4. 使用visualvm远程监控LINUX服务器JVM

    使用visualvm远程监控LINUX服务器JVM 一.JMX方式: 1. 首先要修改JDK中JMX服务的配置文件,以获得相应的权限: 进入$JAVA_HOME所在的根目录的/jre/lib/mana ...

  5. 基于Java的远程监控系统

    基于Java的远程监控系统 功能点: 1.监控桌面 2.文件上传,下载 3.鼠标.键盘等功能 4.命令行控制 1.桌面 2.文件上传下载 3.鼠标.键盘等功能 略 4.命令行控制 输入命令行 cont ...

  6. Java虚拟机性能管理神器 - VisualVM(2) 入门

    一下载VisualVM 最新版本下载 历史版本下载 二启动VisualVM 三VisualVM用户目录 四VisualVM窗口 1应用程序窗口 2详情窗口 五VisualVM插件 Java虚拟机性能管 ...

  7. 深入理解JVM虚拟机_4 JVM内部结构分析-栈

    深入理解JVM虚拟机_4 JVM内部结构分析-栈 作者:田超凡 原创博文,仿冒必究,部分素材转载自每特教育蚂蚁课堂 栈 1. Java 虚拟机栈也是线程私有的,它的⽣命周期和线程相同,描述的是 Jav ...

  8. JVM虚拟机学习 - JVM类加载,JVM内存模型,JVM性能分析工具

    JVM虚拟机 二 JVM类加载 类的生命周期 加载: ​ 加载class文件到二进制字节流,然后再将二进制字节流转化为方法区的运行时数据结构,生成一个对应的Class对象作为类各种数据的访问入口. 链 ...

  9. java虚拟机内存监控_深入理解JVM虚拟机9:JVM监控工具与诊断实践

    本文转自: https://juejin.im/post/59e6c1f26fb9a0451c397a8c 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到 ...

最新文章

  1. 在Putty或mRemote下输入和显示中文
  2. list根据对象进行排序
  3. c++ asc chr 函数_15万怎么选?丰田CHR、本田XRV谁档次高?车主说了心里话
  4. Mybatis源码分析之(三)mapper接口底层原理(为什么不用写方法体就能访问到数据库)
  5. ROS实现两台计算机之间的网络通信
  6. vs2012中编译时出现程序集所使用的版本高于所引用的版本
  7. Vue前端路由~满满的干货
  8. 用例图中三种关系详解(转)
  9. 480.滑动窗口中位数
  10. JavaScript-Date类的getMonth方法释疑
  11. android 手机无线投屏,安卓手机无线投屏问与答
  12. 不同维度、元素的容器vector初始化自定义(C++)
  13. 软件测试工程师简历项目经验怎么写?
  14. HDU5211——Mutiple
  15. NB-IoT(窄带物联网)相关知识
  16. 危险化学品事故爬虫解析
  17. c语言野指针导致问题,C语言进阶之路(三)----野指针的产生原因及解决办法
  18. 西安大明宫上演“灯光秀” 光影融合讲述唐代风韵
  19. 远程终端IP地址查询助手
  20. 数据驱动创新——汽车大数据生态大会在重庆召开

热门文章

  1. oneinstack
  2. Python字符串的修改以及传参
  3. hibernate分页
  4. NOIP2015解题报告 By ljt12138
  5. IIS7.5 HTTP 错误 500 调用loadlibraryex失败的解决方法
  6. FWFT FIFO读操作注意
  7. Windows 7 操作系统核心文件
  8. C#事件的发送方和接收方(订阅方)
  9. nginx和squid配合搭建的web服务器前端系统
  10. Nginx源码分析--数据对齐posix_memalign和memalign函数