我们通常会使用工具jstack 去跟踪线程信息,其如何实现使用attach 的方式还是ptrace 的方式,这些可以去参考本人的博客的其他文章。

但这些方式都是外部使用的方式,如何直接使用java代码得到当前进程的线程的信息,方便监控jvm的整个运行状态,就不的不提到了ManagementFactory

通过调用方法

ThreadMXBean tmbean = ManagementFactory.getThreadMXBean();

通过得到 ThreadMXBean 可以得到非常多的thread信息,博客里也主要提到几个重要函数的实现

ThreadMXBean是个接口,主要实现都是在 ThreadImpl.java 里实现。

1. getThreadCount()

在虚拟机里会有ThreadService,里面会有些计数器用于记录总线程数,活着线程数目

PerfCounter*  ThreadService::_total_threads_count = NULL;
PerfVariable* ThreadService::_live_threads_count = NULL;
PerfVariable* ThreadService::_peak_threads_count = NULL;
PerfVariable* ThreadService::_daemon_threads_count = NULL;
volatile int ThreadService::_exiting_threads_count = 0;
volatile int ThreadService::_exiting_daemon_threads_count = 0;

当线程创建,消亡都会调用 ThreadService 的方法来对计数器加减,这样就能直接得到线程数目的状态,而不需要去遍历线程链表。

2. getAllThreadIds()

这个实现也比较简单,直接扫描线程列表,就可以得到每个java 的线程id, 在扫描过程中使用了锁,锁住了线程链表。 但因为从native代码到java代码中没有锁结构,得到线程的列表只能表示当时的状态,当得到id的时候并不能保证该线程依然存活。

ThreadsListEnumerator::ThreadsListEnumerator(Thread* cur_thread,bool include_jvmti_agent_threads,bool include_jni_attaching_threads) {assert(cur_thread == Thread::current(), "Check current thread");int init_size = ThreadService::get_live_thread_count();_threads_array = new GrowableArray<instanceHandle>(init_size);MutexLockerEx ml(Threads_lock);for (JavaThread* jt = Threads::first(); jt != NULL; jt = jt->next()) {// skips JavaThreads in the process of exiting// and also skips VM internal JavaThreads// Threads in _thread_new or _thread_new_trans state are included.// i.e. threads have been started but not yet running.if (jt->threadObj() == NULL   ||jt->is_exiting() ||!java_lang_Thread::is_alive(jt->threadObj())   ||jt->is_hidden_from_external_view()) {continue;}// skip agent threadsif (!include_jvmti_agent_threads && jt->is_jvmti_agent_thread()) {continue;}// skip jni threads in the process of attachingif (!include_jni_attaching_threads && jt->is_attaching()) {continue;}instanceHandle h(cur_thread, (instanceOop) jt->threadObj());_threads_array->append(h);}
}

我们也可以看到 JNI attach 的线程,和jvmti agent的线程是不被统计在内的

3. ThreadInfo[] getThreadInfo 得到线程具体的堆栈信息

不论是传入要取的线程列表还是要取的所有的线程列表,最后都会看到将取堆栈信息的任务交给了vm thread 线程处理,关于vm thread的作用可以参考本人的其他博客。

  // Obtain thread dumps and thread snapshot informationVM_ThreadDump op(dump_result,thread_handle_array,num_threads,max_depth, /* stack depth */with_locked_monitors,with_locked_synchronizers);VMThread::execute(&op);

a.  vm thread 去遍历所有线程的信息,由于是单线程处理,如果线程数量多的话是会影响到性能的,因为在扫描堆栈过程中,是在softpoint的状态。

b. ThreadDumpResult dump_result(num_threads); 使用ThreadDumpResult 去存储ThreadSnapshot 而保证不会被gc,因为从vm thread抓取线程结束,在填充threadinfo的时候还是会发生gc。

4. 锁的细节显示

在函数 dumpAllThreads(boolean lockedMonitors, boolean lockedSynchronizers)里有2个参数 lockedMonitor, 和 lockedSynchronizer

而这两个参数分别控制两种锁ThreadInfo .getLockedMonitors()  和 ThreadInfo.getLockedSynchronizers()

a.  Monitor 锁

就是我们传统使用的synchronized(Object obj),

可以通过MonitorInfo[]得到具体的锁的数量和信息

b. Locked ownable synchronizers 锁

常指的ReentrantLock 和 ReentrantReadWriteLock 锁

通过得到LockInfo[]  可以得到具体的类,锁的数量和信息

JVM源码系列:ThreadMXBean 打出堆栈信息原理分析相关推荐

  1. c++ map 获取key列表_好未来Golang源码系列一:Map实现原理分析

    分享老师:学而思网校 郭雨田 一.map的结构与设计原理 golang中map是一个kv对集合.底层使用hash table,用链表来解决冲突 ,出现冲突时,不是每一个key都申请一个结构通过链表串起 ...

  2. java源码系列:HashMap底层存储原理详解——4、技术本质-原理过程-算法-取模具体解决什么问题

    目录 简介 取模具体解决什么问题? 通过数组特性,推导ascii码计算出来的下标值,创建数组非常占用空间 取模,可保证下标,在HashMap默认创建下标之内 简介 上一篇文章,我们讲到 哈希算法.哈希 ...

  3. 4、Eureka 源码解析 之 Eureka Client 启动原理分析

    在前面的一篇文章 3.Eureka 源码解析 之 Eureka Server 启动原理分析当中我们分析了一下 Eureka Server 的启动.在集群环境下 Eureka Server 相互之前需要 ...

  4. Java多线程--使用ThreadMXBean 打出堆栈信息

    我们通常会使用工具jstack 去跟踪线程信息,其如何实现使用attach 的方式还是ptrace 的方式,这些可以去参考本人的博客的其他文章. 但这些方式都是外部使用的方式,如何直接使用Java代码 ...

  5. Spring IoC 源码系列(五)getBean 流程分析

    一.FactoryBean 用法讲解 在分析源码流程之前,我们先来看一下 FactoryBean,乍一看这家伙和 BeanFactory 很像,它们都可以用来获取 bean 对象,简单来说 Facto ...

  6. vue3源码系列之计算属性computed原理剖析

    前言 vue3诸多API中computed的作用毋庸置疑,也算是我们开发中使用比较多的API了.今天就让我们来探究下computed底层到底做了什么.如果想要学好computed个人觉得还是需要将ef ...

  7. JVM源码系列:JVM内部运行之Class的Method

    1. Class的属性 在JVM中,通常一个class会初始化成Klass(接口), InstanceKlass(实例), Method(方法), ConstantsPool(常量区) 在上图我们可以 ...

  8. java源码系列:HashMap底层存储原理详解——5、技术本质-原理过程-算法-取模会带来一个什么问题?什么是哈希冲突?为什么要用链表?

    目录 取模会带来一个什么问题? 演示什么是哈希冲突(哈希碰撞)? 为什么要用链表? 其他--布隆过滤器 取模会带来一个什么问题? 好,那同学们这样他能达到一个目的,但是呢,它也会带来的一个问题,那它会 ...

  9. Spring源码系列(十二)Spring创建Bean的过程(二)

    1.写在前面 上篇博客主要Spring在创建Bean的时候,第一次调用的Bean的后置处理器的过程,同时笔者也打算将整个Spring创建的Bean的过程,通过这个系列,将Bean的创建过程给讲清楚,废 ...

最新文章

  1. 人工智能学习知识框架(知识点、实际应用)-思维导图汇总-xmind原图
  2. [MATLAB粒子模拟笔记]差分泊松方程求静电场分布
  3. java三目运算符嵌套_替代JS中的嵌套三元运算符
  4. javascript --- 实现Ajax的代码
  5. 趣挨踢 | 跳槽季,让我们一起攻克算法吧!
  6. 工业机器人演示码垛和卸垛_众多企业购买自动码垛机的原因是什么?
  7. 文本模式下安装Oracle 10g
  8. 电脑工具栏怎么调整到下面_PDF格式的合同怎么盖公章?这不是在为难我胖虎吗?...
  9. pku2192(并查集+枚举)
  10. 腾讯视频怎么获得html代码,如何获取腾讯视频等九大视频网站的视频分享代码...
  11. oracle中那个日期怎么相减_oracle 日期相减
  12. 高通QPST Download使用方法
  13. 88E1111使用记录
  14. finalcut剪切快捷键_final cut pro怎么用快捷键把时间线上的素材移动到入点或剪辑点...
  15. CToolBar的使用总结(1)
  16. 布道微服务_11监控系统选型与常见方案
  17. Apache DolphinScheduler 是如何诞生的
  18. 海康威视录像机如何添加大华摄像头
  19. 计算机无法识别苹果6手机软件,电脑里安装的itunes不能识别我的苹果6sp… - Apple 社区...
  20. 新型冠状病毒全国疫情新浪腾讯网易API接口json

热门文章

  1. 高分影像批处理第二回——辐射定标与大气校正
  2. Windows下单机安装Spark开发环境
  3. 计算领域中的数学知识都有哪些?
  4. WATLOW EHG SL10 EHG2-CNTL-0000
  5. 想成为优秀UI设计师 如何系统地学习UI设计
  6. 艾美捷CpG ODN——ODN 1720 (TLRGRADE)说明书
  7. 你不知道的“探探”引流套路,让更多人“喜欢你”!
  8. 元宇宙基础知识全汇总
  9. jieba 同义词_Jieba库实现词性标注及小说人物角色抽取
  10. 日语 N5知识点 -助词