JVM监控与故障处理

    现实企业级java开发中,有时候我们会碰到下面这些问题:

  • OutOfMemoryError内存不足
  • 内存泄露
  • 线程死锁
  • 锁争用(lock Contention)
  • Java进程消耗CPU过高
  • ... ... 等等
    这些问题在日常开发中可能被很多人忽视(比如遇到上面这些问题就重启服务器或者跳大内存,而不会深究问题根源),但能够解决这些问题是Java程序员的必备需求。JDK本身提供了很多JVM性能调优监控工具,除了集成式的VisualVM和JConsole外,还有jps、jstack、jmap、jstat、hprof等小工具。     jps主要用来输出jvm中运行的进程状态信息。语法格式如下:jps 【options】 【hostid】。如果不指定hostid就默认为当前主机或服务器。命令行参数选项说明如下:     例如下面: 二、jstack     jstack主要用来查看某个Java进程内的线程堆栈信息。语法格式如下:     命令行参数说明如下:     jstack可以定位到线程堆栈,根据堆栈信息定位到具体代码,所以他在jvm性能调优中使用的非常多。下面通过一个实例找出某个java进程中最耗费CPU的Java线程并定位堆栈信息,用到的命名有ps、top、prinf、jstack、grep。     ①先找出java进程ID,部署在服务器上的java应用名称为mrf-center: 得到进程ID为21711。     ②找出该进程内消耗CPU的线程,可以使用ps -Lfp  pid或者ps -mp pid -o THREAD,tid,time或者top -Hp pid,这里用第三个,输出如下:
   TIME列就是各个Java线程耗费CPU时间,CPU时间最长的线程ID为21742的线程,用【printf "%x\n" 21742】得到21742的十六进制为54ee,下面会用到。     下一步终于轮到jstack上场了,他用来输出进程21711的线程,然后根据线程ID的十六进制值grep,如下:     可以看到CPU消耗在PollIntervalRetrySchedulerThread这个类的Object.wait(),找到该代码,定位到下面的代码:     它是轮训任务的空闲等待代码,上面的sigLock.wait(timeUntilContinue)就对应了前面的Object.wait。 三、jmap(Memory Map)和jhat(java heap Analysis tool)     jmap用来查看堆内存使用状况,一般结合jhat使用。     jmap的语法格式如下:     如果运行在64位JVM上,可能需要指定-j-d64命令选项参数。     打印进程的类加载器和类加载器的持久代对象信息,输出:类加载器名称、对象是否存活(不可靠)、对象地址、父类加载器、已加载的类大小等信息,如下图:
   使用jmap -heap pid查看进程堆内存使用情况,包括使用的GC算法、堆配置参数和各代中堆内存使用情况。比如下面的例子:     使用jmap -histo[:live] pid查看堆内存中的对象数目、大小统计直方图,如果当上live则只统计活对象,如下:     class name是对象类型,说明如下:     还有一个很常用的情况是:用jmap把内存使用情况dump到文件中,在用jhat分析查看。jmap进行dump命令格式如下:     例如对上面ID为21711进行dump:     dump出来的文件可以使用mat、VisualVM等工具查看,这里用jhat查看:     注意如果dump文件太大,可能需要加上-J-Xmx512m这种参数指定最大堆内存,即jhat -J-Xmx512m -port 9998 /tmp/dump.dat。然后可以在浏览器中输入主机地址:9998查看了,如下:
   上面红线框出来的部分大家可以自己去探索下,最后一项是支持OQL(对象查询语言) 四、jstat(JVM统计监测工具)     语法格式如下:     vmid是java虚拟机ID,在linux/unix系统上一般就是进程ID。interval是采样时间间隔。count是采样数目。比如下面输出的GC信息,采样时间间隔为250ms,采样数为4:     要明白上面各列的意义,先看JVM堆内存布局:     可以看出:     现在来解释各列含义:  五、hprof(Heap/CPU Profiling Tool)    hprof能够展现CPU使用率,统计堆内存使用情况。语法格式如下:     完成的命令选项如下:    来几个官方指南的例子:CPU Usage Sampling Profiling(cpu=samples)的例子     上面间隔20毫秒采样cpu消耗信息,堆栈深度为3,生成的profile文件名称为java.hprof.txt,在当前目录。     CPU Usage Times Profiling(cpu=times)的例子,它相对于CPU Usage Sampling Profile能够获得更细粒度的CPU消耗信息,能够细到每个方法调用的开始和结束,它的实现使用了字节码注入技术:     Heap Allocation Profiling(heap=sites)的例子:     Heap Dump(heap=dump)的例子,它比上面的Heap Allocation Profiling能生成更详细的heap dump信息:     虽然在jvm启动参数中加入-Xrunprof:heap=sites参数可以生成cpu/heap profile文件,但对jvm性能影响非常大,不建议在线上服务器环境使用。   转子:https://my.oschina.net/feichexia/blog/196575

猜你喜欢

转载自student-lp.iteye.com/blog/2302435