展开全部

当有障碍,或者是一个基于 JAVA 的 WEB 应用运行的比预期32313133353236313431303231363533e58685e5aeb931333337623537慢的时候,我们需要使用 thread dumps。如果对于你来说,thread dumps 是非常复杂的,这篇文章或许能对你有所帮助。在这里我将解释在 JAVA 中什么是 threads,他们的类型,怎么被创建的,怎样管理它们,你怎样从正在运行的应用中 dump threads,最后你可以怎样分析它以及确定瓶颈或者是阻塞线程。本文来自于 JAVA 应用程序长期调试经验的结果。

Java and Thread

一个 web 服务器使用几十到几百个线程来处理大量并发用户,如果一个或多个线程使用相同的资源,线程之间的竞争就不可避免了,并且有时候可能会发生死锁。

Thread contention 是一个线程等待锁的一个状态,这个锁被另外一个线程持有,等待被释放,不同的线程频繁访问 WEB 应用的共享资源。例如,记录一条日志,线程尝试记录日志之前必须先获取锁来访问共享资源。

死锁是线程竞争的一个特殊状态,一个或是多个线程在等待其他线程完成它们的任务为了完成它们自己的任务。

线程竞争会引起各种不同的问题,为了分析这些这些问题,你需要使用 dump threads,dump threads 能给你提供每个线程的精确状态信息。

JAVA 线程的背景资料

线程同步

一个线程可以与其他线程在同一时间内被处理。为了确保一致性,当多个线程试图使用共享资源的时候,通过使用 hread synchronization 在同一时间内,应该只有一个线程能访问共享资源

JAVA 中的线程同步可以使用监视器,每个 JAVA 对象都有一个单独的监视器,这个监视器仅仅只能被一个线程拥有,对于拥有一个由不同的线程所拥有的监视器的线程,确实需要在队列中等待,以便其他线程释放它的监视器。

线程状态

为了分析一个 thread dump 文件,你需要知道线程状态。线程情况在 java.lang.Thread.State 中阐明了。

获取一个

Thread Dump

我们将介绍三种最常用的方法,记住,有非常多的其他方法可以获取thread dump,一个 thread dump 仅仅只能在测量的时候显示线程状态。因此为了看得线程状态的变化,建议每隔5秒提取5到10次的记录。

使用

jstack 获取 Thread Dump

在 JDK1.6 或者是更高的版本中,通过使用 jstack,

在 MS Windows 平台上可能可以获取到 Thread Dump。

通过使用 jps 检查当前正在运行的JAVA进程的

PID。

[user@linux ~]$ jps -v

25780 RemoteTestRunner -Dfile.encoding=UTF-8

25590 sub.rmi.registry.RegistryImpl 2999 -Dapplication.home=/home1/user/java/jdk.1.6.0_24 -Xms8m

26300 sun.tools.jps.Jps -mlvV -Dapplication.home=/home1/user/java/jdk.1.6.0_24 -Xms8m

使用明确的 PID 作为 jstack 的参数来获取 thread dumps。

[user@linux ~]$ jstack -f 5824

使用

jVisualVM 生成 Thread Dump

通过使用一个程序 jVisualVM 来生成 Thread Dump。

当使用 java.lang.Thread 对象创建线程的时候,线程被命名为 Thread-(Number) 。当使用 java.util.concurrent.DefaultThreadFactory 对象创建线程的时候,线程被命名为 named pool-(Number)-thread-(Number)。当为应用程序分析成百上千的线程的时候,如果线程依然用它们默认的名字,分析它们将变得非常困难,因为这是非常难以辨别这些线程来分析的。

因此,你被建议开发一个命名线程的规则当一个新线程被创建的时候。

当你使用 java.lang.Thread 创建线程,你可以通过创建参数给该线程定义个约定俗成的名字。

public Thread(Runnable target, String name);

public Thread(ThreadGroup group, String name);

public Thread(ThreadGroup group, Runnable target, String name);

public Thread(ThreadGroup group, Runnable target, String name, long stackSize);

当你使用 java.util.concurrent.ThreadFactory 创建线程的时候,你可以通过生成你自己的线程工厂来命名它,如果你不需要特别的功能性,你可以使用 MyThreadFactory 作为以下描述:

import java.util.concurrent.ConcurrentHashMap;

import java.util.concurrent.ThreadFactory;

import java.util.concurrent.atomic.AtomicInteger;

public class MyThreadFactory implements ThreadFactory {

private static final ConcurrentHashMap POOL_NUMBER =

new ConcurrentHashMap();

private final ThreadGroup group;

private final AtomicInteger threadNumber = new AtomicInteger(1);

private final String namePrefix;

public MyThreadFactory(String threadPoolName) {

if (threadPoolName == null) {

throw new NullPointerException("threadPoolName");

}

POOL_NUMBER.putIfAbsent(threadPoolName, new AtomicInteger());

SecurityManager securityManager = System.getSecurityManager();

group = (securityManager != null) ? securityManager.getThreadGroup() :

Thread.currentThread().getThreadGroup();

AtomicInteger poolCount = POOL_NUMBER.get(threadPoolName);

if (poolCount == null) {

namePrefix = threadPoolName + " pool-00-thread-";

} else {

namePrefix = threadPoolName + " pool-" + poolCount.getAndIncrement() + "-thread-";

}

}

public Thread newThread(Runnable runnable) {

Thread thread = new Thread(group, runnable, namePrefix + threadNumber.getAndIncrement(), 0);

if (thread.isDaemon()) {

thread.setDaemon(false);

}

if (thread.getPriority() != Thread.NORM_PRIORITY) {

thread.setPriority(Thread.NORM_PRIORITY);

}

return thread;

}

}

使用 MBean 获取更多的细节信息

你可以使用 MBean 来获取 ThreadInfo 对象。你也可以获取更加多通过 thread dumps 不能获取的信息。通过使用 ThreadInfo。

ThreadMXBean mxBean = ManagementFactory.getThreadMXBean();

long[] threadIds = mxBean.getAllThreadIds();

ThreadInfo[] threadInfos =

mxBean.getThreadInfo(threadIds);

for (ThreadInfo threadInfo : threadInfos) {

System.out.println(

threadInfo.getThreadName());

System.out.println(

threadInfo.getBlockedCount());

System.out.println(

threadInfo.getBlockedTime());

System.out.println(

threadInfo.getWaitedCount());

System.out.println(

threadInfo.getWaitedTime());

}

你可以使用方法 ThreadInfo 来提取阻塞线程或者是等待线程花费的时间。并利用这一点,你也可以得到那些处于非活动状态的时间异常长的线程列表。

本回答由提问者推荐

已赞过

已踩过<

你对这个回答的评价是?

评论

收起

java 怎样 thread dump_怎样分析 JAVA 的 Thread Dumps相关推荐

  1. 利用java虚拟机的工具jmap分析java内存情况

    2019独角兽企业重金招聘Python工程师标准>>> 有时候碰到性能问题,比如一个java application出现out of memory,出现内存泄漏的情况,再去修改bug ...

  2. java lam表达式_详细分析Java Lambda表达式

    在了解Lambda表达式之前我们先来区分一下面向对象的思想和函数式编程思想的区别 面向对象的思想: 做一件事情,找一个能解决这个事情的对象,调用他的方法来解决 函数时编程思想: 只要能获取到结果,谁去 ...

  3. Java虚拟机:深入详细分析Java ClassLoader原理与源码

    一.什么是ClassLoader? ClassLoader就是类加载器,当我们写好一个Java程序之后,都是由若干个.class文件组成的一个完整的Java应用程序,当程序在运行时,即会调用该程序的一 ...

  4. java jmap 分析_利用java虚拟机的工具jmap分析java内存情况

    有时候碰到性能问题,比如一个java application出现out of memory,出现内存泄漏的情况,再去修改bug可能会变得异常复杂,利用工具去分析整个java application 内 ...

  5. jdt 解析java语句,利用JDT 回分析java 源代码

    项目里需要扫代码的sql,主要是想找出所有用到的sql. 将相关的sql 提交给DBA 来分析,希望在最早的时间发现潜在的查询性能问题. 想想eclipse 里面用到的JDT 能分析java 源代码, ...

  6. 没有体现JAVA接口功能_深入浅出分析Java抽象类和接口【功能,定义,用法,区别】...

    本文实例讲述了Java抽象类和接口.分享给大家供大家参考,具体如下: 对于OOP编程来说,抽象是它一大特征之一.在Java中,可以通过两种形式来体现OOP的抽象:抽象类和接口. 这两者有相似之处也有很 ...

  7. java 线程等待_代码分析Java中线程的等待与唤醒

    我们先来看一下实例代码: class ThreadA extends Thread{ public ThreadA(String name) { super(name); } public void ...

  8. Java Volatile关键字可见性问题分析

    Java Volatile关键字可见性问题分析 Java 内容模型 普通变量(非Vola变量)的内存不可见性 Volatile变量的内存可见性 剩余疑惑 Java 内容模型 具体可以查看这篇文章Jav ...

  9. java 和 Android Base64加密,java开发面试笔试题

    我总结出了很多互联网公司的面试题及答案,并整理成了文档,以及各种学习的进阶学习资料,免费分享给大家. 扫描二维码或搜索下图红色VX号,加VX好友,拉你进[程序员面试学习交流群]免费领取.也欢迎各位一起 ...

最新文章

  1. 应对百度算法调整的三大优化技巧
  2. python中的解析式是什么_初学python之解析式
  3. kill linux 信号量,kill用法详细解释(特别是信号量9的使用以及理解)
  4. Flutter 异常处理之图片篇
  5. linux怎么打开q7后缀的文件,ZQ7 文件扩展名: 它是什么以及如何打开它?
  6. oopc——3.封装
  7. 线程同步--事件内核对象
  8. 我对骨骼动画的理解(最精减的骨骼动画类)
  9. 定义并调用函数 十进制转二进制_用‘栈的思想编写一个十进制转换二进制、八进制或十六进制的程序...
  10. 企业权限管理系统如何配置?深度解析永洪BI权限管理系统
  11. c语言编程if语句的用法,if句子用法(C语言中,if语句的用法)
  12. 斐讯路由器虚拟服务器怎么设置,斐讯PSG1218路由器如何设置
  13. 让人懵逼的宏定义赋值
  14. Cache entry deserialization failed, entry ignored 错误解决
  15. Unsupervised Cross-Dataset Transfer Learning for Person Re-identification阅读总结
  16. 笔谈OpenGL ES(三)
  17. 国家初中学生体质测试评分软件,国家学生体质健康标准评分表__小学,初中,高中...
  18. Unity 向目标移动,并朝向目标
  19. FFmpeg —— mp4文件转为avi无损文件(附源码)
  20. 走近Hinton:AI教父传奇人生

热门文章

  1. python深度学习第四讲——python神经网络参数更新
  2. js已知文件路径得到file对象_NodeJs 的几种文件路径
  3. js table多层嵌套_只会console.log?8个高效调试js的console方法
  4. 今天日期减去过去日期_汽车各零部件也有身份证,教你们如何看这些部件的quot;出生日期quot;...
  5. 跨境电商ERP管理,让你节约跟多时间!
  6. Leetcode每日一题:31.next-permutation(下一个全排列)
  7. 数学建模 聚类模型
  8. Java并发(一)——线程
  9. Confluence 6 已经存在的安装配置数据库字符集编码
  10. spirng底层实现原理