Linux下Java线程详细监控和其dump的分析使用----分析Java性能瓶颈

标签: linux java 线程 | 发表时间:2014-08-14 00:21 | 作者:tianya846
出处:http://blog.csdn.net
这里对linux下、sun(oracle) JDK的线程资源占用问题的查找步骤做一个小结;
linux环境下,当发现java进程占用CPU资源很高,且又要想更进一步查出哪一个java线程占用了CPU资源时,按照以下步骤进行查找:

(一):通过【 top  -p 12377 -H】 查看java进程的有哪些线程的运行情况;
      和通过【jstack 12377 > stack.log】生成Java线程的dump详细信息;

    1. 先用top命令找出占用资源厉害的java进程id,如图:# top
    2. 如上图所示,java的进程id为'52554',接下来用top命令单独对这个进程中的所有线程作监视:
  1. 1 top  -p 52554 -H

    #  top视图里面里面可以通过快捷键依次b ,x高亮显示top的列找出需要的线程,默认CPU排序,Shift+< ,Shift+>可以左右移动高亮排序的列;
    如图:(这时就看出来哪个java线程CPU高,哪个线程内存用的多)

  2. 如上图所示,linux下,所有的java内部线程,其实都对应了一个进程id,也就是说,linux上的sun jvm将java程序中的线程映射为了操作系统进程;我们看到,占用CPU资源最高的那个进程id是'15417',这个进程id对应java线程信息中的'nid'('n' stands for 'native');
  3. (1)要想找到到底是哪段具体的代码占用了如此多的资源,先使用jstack打出当前栈信息到一个文件里, 比如stack.log:
    1
    jstack 52554 > stack.log
    然后使用'jtgrep'脚本把这个进程号为'9757'的java线程在stack.log中抓出来:
    1 jtgrep 9757 stack.log

    其中,'jtgrep'是自己随便写的一个shell脚本:

    1 #!/bin/sh
    3 nid=`python -c  "print hex($1)" `
    4 grep  -i $nid $2

    道理很简单,就是 把'9757'转换成16进制后,直接grep stack.log;可以看到,被grep出的那个线程的nid=0x3c39,正好是15417的16进制表示。

(2) 通过(windows程序-->计算器),选择程序员计算器将进程ID转换成16进制 到dump里面的nid 就可以搜索到
"http-nio-8080-exec-25" daemon prio=10 tid=0x00007f69686b4800 nid=0x1ce5 waiting on condition [0x00007f698e7cf000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x0000000777063ec8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(Unknown Source)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(Unknown Source)
        at java.util.concurrent.LinkedBlockingQueue.take(Unknown Source)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:104)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:32)
        at java.util.concurrent.ThreadPoolExecutor.getTask(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)

(二)第二种通过 Java visualMv结合 jconsole.exe   工具即可查看如图所示;(第一种方式可能更准确一些)






三:在Java Visualvm工具里面安装JTA插件,分析线程dump文件,注意,正常阶段的dump文件与非正常时期的Dump文件进行比较更容易分析出问题:
(1)下载:https://java.net/projects/tda/downloads/directory/visualvm
  (2)安装与使用:
(3)使用:


四:直接通过tda-bin-2.2\bin\tda.sh 来分析导出ThreadDump文件;(在没有JMX监控的情况下手动查看threadDump信息)
       下载地址:https://java.net/projects/tda/downloads/directory/visualvm 
 





























作者:tianya846 发表于2014-8-13 16:21:16 原文链接
阅读:64 评论:1 查看评论

相关 [linux java 线程] 推荐:

Java线程与Linux内核线程的映射关系

- - CSDN博客编程语言推荐文章
Linux从内核2.6开始使用NPTL (Native POSIX Thread Library)支持,但这时线程本质上还轻量级进程. Java里的线程是由JVM来管理的,它如何对应到操作系统的线程是由JVM的实现来确定的. Linux 2.6上的HotSpot使用了NPTL机制, JVM线程跟内核轻量级进程有一一对应的关系.

Linux下Java线程详细监控和其dump的分析使用----分析Java性能瓶颈

- - CSDN博客互联网推荐文章
这里对linux下、sun(oracle) JDK的线程资源占用问题的查找步骤做一个小结;. linux环境下,当发现java进程占用CPU资源很高,且又要想更进一步查出哪一个java线程占用了CPU资源时,按照以下步骤进行查找:. -p 12377 -H】 查看java进程的有哪些线程的运行情况;.

Java线程池

- - 企业架构 - ITeye博客
线程的使用在java中占有极其重要的地位,在jdk1.4极其之前的jdk版本中,关于线程池的使用是极其简陋的. 在jdk1.5之后这一情况有了很大的改观. Jdk1.5之后加入了java.util.concurrent包,这个包中主要介绍java中线程以及线程池的使用. 为我们在开发中处理线程的问题提供了非常大的帮助.

Java 线程池

- - 编程语言 - ITeye博客
在项目中,系统启动一个新线程的成本是比较高的,因为它涉及与操作系统交互. 在这种情形下,使用线程池可以很好地提高性能,尤其是当程序中需要创建大量生存周期很短的线程时,更应该考虑使用线程池. 使用线程池可以有效地控制系统中并发线程的数量,当系统中包含大量并发线程时,会导致系统性能剧烈下降,甚至导致JVM崩溃,而线程池的最大线程数参数可以控制系统中并发线程数不超过此数.

Java Thread多线程

- - CSDN博客推荐文章
Java Thread多线程. Java 多线程例子1 小例子. super("zhuyong");//设置线程的名字,默认为“TestThread”. Java 多线程例子2 前台线程(用户线程) 后台线程(守护线程 ). 1,setDaemon(true)后就是后台线程(守护线程 ),反之就是前台线程(用户线程).

Java线程之FutureTask

- - zzm
FutureTask是Future和Callable的结合体. 然后通过Future来取得计算结果. 但是,若开启了多个任务,我们无从知晓哪个任务最先结束,因此,若要实现“当某任务结束时,立刻做一些事情,例如记录日志”这一功能,就需要写一些额外的代码. FutureTask正是为此而存在,他有一个回调函数protected void done(),当任务结束时,该回调函数会被触发.

python/java操作linux系统命令

- 天朝小民 - ITeye论坛最新讨论
看来python的确是做为脚本语言来使用的话,非常的方便. 来看一个处理linux命令的脚本. #coding:utf-8 import os import commands ''' 采用os.popen(cmd)来执行命令,要获取输出,需要read()来读取 ''' cmd = 'ls -l' values = os.popen(cmd).read() #print values for v in values.split('\n'):.

[Java] Java 多线程案例分析

- - V2EX
现要从 hbase中导出 2016 年整年的,大约 10w只股票行情数据,数据总量约 100t. 汇总到 hdfs中供需求方使用. 已知数据量规模大概是 100t,那么单台机器处理肯定不是不行的,先不说大多数磁盘都没这么大,即便磁盘有这么大,单台机器处理对于内存和 cpu 要求也很高,所以我们将问题一般化,使用数量有限的低配机器.

Java多线程之synchronized

- - CSDN博客推荐文章
这里通过三个测试类阐述了synchronized应用的不同场景. 首先是最基本的synchronized Method的使用.  * @see 概述:Java中的每个对象都有一个锁(lock)或者叫做监视器(monitor) .  * @see 说明:当synchronized关键字修饰一个方法时,则该方法为同步方法 .

java线程池分析

- - BlogJava-首页技术区
    在Java 5.0之前启动一个任务是通过调用Thread类的start()方法来实现的,任务的提于交和执行是同时进行的,如果你想对任务的执行进行调度或是控制 同时执行的线程数量就需要额外编写代码来完成. 5.0里提供了一个新的任务执行架构使你可以轻松地调度和控制任务的执行,并且可以建立一个类似数据库连接 池的线程池来执行任务.