`

JVM 内部运行线程介绍

阅读更多

详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp47


最近在找关于JVM内部线程管理的资料,发现网上相关帖子很少,有一些还是胡说的,下面这个文章看起来还是不错的,虽然有一点儿乱,但是也得为作者致敬了。

最近抽时间把JVM运行过程中产生的一些线程进行了整理,主要是围绕着我们系统jstack生成的文件为参照依据。  前段时间因为系统代码问题,造成性能瓶颈,于是就dump了一份stack出来进行分析。stack 里面线程非常多,排查起来需要一定的经验,所以,对它们有一定了解,可以提高排查问题的效率。现在网上资料也不是特别全,所以,导致很多新人在拿到一个stack文件之后,也不知知道从何看起。下面我把这次整理的一些个人认为比较常见的线程列出来。




所属





Attach Listener





          Attach Listener线程是负责接收到外部的命令,而对该命令进行执行的并且吧结果返回给发送者。通常我们会用一些命令去要求jvm给我们一些反馈信息,如:java -version、jmap、jstack等等。如果该线程在jvm启动的时候没有初始化,那么,则会在用户第一次执行jvm命令时,得到启动。





JVM





CompilerThread0





       用来调用JITing,实时编译装卸class。通常,jvm会启动多个线程来处理这部分工作,线程名称后面的数字也会累加,例如:CompilerThread1





JVM





DestroyJavaVM





执行main()的线程在main执行完后调用JNI中的jni_DestroyJavaVM()方法唤起DestroyJavaVM线程。   JVM在Jboss服务器启动之后,就会唤起DestroyJavaVM线程,处于等待状态,等待其它线程(java线程和native线程)退出时通知它卸载JVM。线程退出时,都会判断自己当前是否是整个JVM中最后一个非deamon线程,如果是,则通知DestroyJavaVM线程卸载JVM。ps:扩展一下:1.如果线程退出时判断自己不为最后一个非deamon线程,那么调用thread->exit(false),并在其中抛出thread_end事件,jvm不退出。2.如果线程退出时判断自己为最后一个非deamon线程,那么调用before_exit()方法,抛出两个事件: 事件1:thread_end线程结束事件、事件2:VM的death事件。然后调用thread->exit(true)方法,接下来把线程从active list卸下,删除线程等等一系列工作执行完成后,则通知正在等待的DestroyJavaVM线程执行卸载JVM操作。







JBOSS





ConfigClientNotifier





         ConfigServer服务端当有配置变更时,就会将最新的配置推送到ConfigServer客户端的一个数据列队中,ConfigClientNotifier线程用于定期检查该数据列队中是否有数据,如果有数据,则将数据分发到订阅该数据的组件去做业务逻辑,比如:tair和hsf的数据都订阅了ConfigServer数据源,当ConfigClientNotifier线程发现数据有更新时,就触发做数据分发特定特定信号标识将数据分发到相应的订阅者。





ConfigServer





Dispatcher-Thread-3





      Log4j具有异步打印日志的功能,需要异步打印日志的Appender都需要注册到AsyncAppender对象里面去,由AsyncAppender进行监听,决定何时触发日志打印操作。AsyncAppender如果监听到它管辖范围内的Appender有打印日志的操作,则给这个Appender生成一个相应的event,并将该event保存在一个buffuer区域内。  Dispatcher-Thread-3线程负责判断这个event缓存区是否已经满了,如果已经满了,则将缓存区内的所有event分发到Appender容器里面去,那些注册上来的Appender收到自己的event后,则开始处理自己的日志打印工作。Dispatcher-Thread-3线程是一个守护线程。





JVM





Gang worker#0





JVM用于做新生代垃圾回收(monir gc)的一个线程。#号后面是线程编号,例如:Gang worker#1





JVM





IdleRemover





Jboss连接池有一个最小值,该线程每过一段时间都会被Jboss唤起,用于检查和销毁连接池中空闲和无效的连接,直到剩余的连接数小于等于它的最小值。





JVM





FelixDispatchQueue





       该线程会在sofa启动时会唤起该线程,该线程用于分发OSGI事件到Declarative Services 中去发布,查找,绑定目标服务。其实,我们接口配置的service和reference就涉及到服务的发布、查找和绑定工作。   Declarative Services 主要工作职责是方便地对服务之间的依赖关系和状态进行监听和管理。OSGI使用事件策略去调用Declarative Services中的服务。







Quartz





InsttoolCacheScheduler_

Worker-2





InsttoolCacheScheduler_Worker-2线程就是ThreadPool线程的一个简单实现,它主要负责分配线程资源去执行InsttoolCacheScheduler_QuartzSchedulerThread线程交给它的调度任务(也就是JobRunShell)。







JVM





JBossLifeThread





        Jboss主线程启动成功,应用程序部署完毕之后将JBossLifeThread线程实例化并且start,JBossLifeThread线程启动成功之后就处于等待状态,以保持Jboss Java进程处于存活中。 所得比较通俗一点,就是Jboss启动流程执行完毕之后,为什么没有结束?就是因为有这个线程hold主了它。牛b吧~~





Jboss





JCA PoolFiller





   该线程主要为JBoss内部提供连接池的托管。 简单介绍一下工作原理 :Jboss内部凡是有远程连接需求的类,都需要实现ManagedConnectionFactory接口,例如需要做JDBC连接的XAManagedConnectionFactory对象,就实现了该接口。然后将XAManagedConnectionFactory对象,还有其它信息一起包装到InternalManagedConnectionPool对象里面,接着将InternalManagedConnectionPool交给PoolFiller对象里面的列队进行管理。   JCA PoolFiller线程会定期判断列队内是否有需要创建和管理的InternalManagedConnectionPool对象,如果有的话,则调用该对象的fillToMin方法,触发它去创建相应的远程连接,并且将这个连接维护到它相应的连接池里面去。





JVM





JDWP TransportListener: dt_socket





该线程是一个Java Debugger的监听器线程,负责受理客户端的debug请求。通常我们习惯将它的监听端口设置为8787。





JVM





process reaper





   该线程负责去执行一个OS命令行的操作。





JVM





SurrogateLockerThread

(CMS)





          这个线程主要用于配合CMS垃圾回收器使用,它是一个守护线程,其主要负责处理GC过程中,Java层的Reference(指软引用、弱引用等等)与jvm内部层面的对象状态同步。这里对它们的实现稍微做一下介绍:这里拿WeakHashMap做例子,将一些关键点先列出来(我们后面会将这些关键点全部串起来):

1.      我们知道HashMap用Entry[]数组来存储数据的,WeakHashMap也不例外,内部有一个Entry[]数组。

3.      Reference里面有一个全局锁对象:Lock,它也被称为pending_lock.   注意:它是静态对象。

5. Reference 里面有一个静态内部类:ReferenceHandler的线程,它在static块里面被初始化并且启动,启动完成后处于wait状态,它在一个Lock同步锁模块中等待。

7.      上面关键点就介绍完毕了,下面我们把他们串起来。



taskObjectTimerFactory





         顾名思义,该线程就是用来执行任务的。当我们把一个任务交给Timer对象,并且告诉它执行时间,周期时间后,Timer就会将该任务放入任务列队,并且通知taskObjectTimerFactory线程去处理任务,taskObjectTimerFactory线程会将状态为取消的任务从任务列队中移除,如果任务是非重复执行类型的,则在执行完该任务后,将它从任务列队中移除,如果该任务是需要重复执行的,则计算出它下一次执行的时间点。





JVM





VM Thread





        这个线程就比较牛b了,是jvm里面的线程母体,根据hotspot源码(vmThread.hpp)里面的注释,它是一个单例的对象(最原始的线程)会产生或触发所有其他的线程,这个单个的VM线程是会被其他线程所使用来做一些VM操作(如,清扫垃圾等)。在 VMThread的结构体里有一个VMOperationQueue列队,所有的VM线程操作(vm_operation)都会被保存到这个列队当中,VMThread本身就是一个线程,它的线程负责执行一个自轮询的loop函数(具体可以参考:VMThread.cpp里面的void VMThread::loop()),该loop函数从VMOperationQueue列队中按照优先级取出当前需要执行的操作对象(VM_Operation),并且调用VM_Operation->evaluate函数去执行该操作类型本身的业务逻辑。ps:VM操作类型被定义在vm_operations.hpp文件内,列举几个:ThreadStop、ThreadDump、PrintThreads、GenCollectFull、GenCollectFullConcurrent、CMS_Initial_Mark、CMS_Final_Remark…..有兴趣的同学,可以自己去查看源文件。



分享到:
评论

相关推荐

    java 查看JVM中所有的线程的活动状况

    在Java编程环境中,了解JVM(Java虚拟机)中所有线程的活动状态对于调试多线程程序至关重要。本文将详细讲解如何查看JVM中的线程活动情况,并提供相关示例代码。 首先,Java提供了`java.lang.management....

    jvm和多线程学习资料1,经典资料

    【标签】"java 课程资源"表明这些资料适合于教学或自我学习,是Java课程中可能涉及的主题,特别是关于JVM内部机制和如何在Java环境中有效地使用多线程。 【压缩包子文件的文件名称列表】中的两个文件: 1. "Java多...

    vmmap 观察jvm内存 监控jvm jvm线程

    - 结合`jstack`工具,可以获取JVM内部线程的详细信息,包括线程状态、阻塞原因等,帮助诊断线程死锁或过度竞争问题。 4. **优化策略:** - 调整JVM参数,如堆大小(`-Xms`和`-Xmx`)、新生代比例(`-XX:NewRatio`)、...

    Java分布式应用学习笔记03JVM对线程的资源同步和交互机制

    Java作为一种广泛应用于分布式系统开发的编程语言,其内部机制,尤其是JVM对于线程的管理和资源的同步,是确保程序高效、稳定运行的关键。 #### 线程与多线程 线程是操作系统能够进行运算调度的最小单位,它被包含...

    JVM监控实例数 windows监控 线程测试 单例模式下测试JVM实例是否一个

    为了确保应用程序高效稳定地运行,开发者需要对JVM进行监控,了解其内部状态,如内存使用、线程活动等。本文将探讨如何在Windows环境下通过简单的命令行工具来监控JVM实例的数量,以及如何进行线程测试,特别是在...

    JVM线程学习

    在JVM内部,线程是由操作系统的原生线程支持的,Java线程与这些原生线程有一一对应的关系。线程调度策略(抢占式和合作式)和线程上下文切换对性能有很大影响。此外,书中还可能涵盖了线程局部存储,这是一种每个...

    java进阶提高学习教程-13JVM与多线程.pptx

    - **线程创建**:可通过继承Thread类、实现Runnable接口或使用匿名内部类创建线程。 - **线程常用的方法**:如sleep()使线程休眠,join()等待线程结束,setPriority()设置优先级,yield()让出CPU,setDaemon()将线程...

    java-基础/jvm/多线程

    "Java-基础/jvm/多线程"这个主题涵盖了Java语言的基础知识,包括JVM(Java虚拟机)、多线程以及Java的基础语法和特性。 1. **JVM、JRE和JDK的关系**: - JVM(Java Virtual Machine)是Java程序运行的平台,负责...

    jdk,jvm源码

    当我们谈论"jdk,jvm源码"时,我们主要关注的是JVM的内部工作机制以及如何通过源码来理解这个过程。 JVM的运行机制主要包括以下几个关键部分: 1. 类加载子系统:负责加载、验证、解析和初始化.class文件。加载阶段...

    java 核心知识 包含 JVM 线程 集合 数据库 算法 负载等一系列

    JVM是Java程序运行的基石,它负责解析字节码并执行。理解JVM的工作原理,包括类加载机制、内存管理(堆、栈、方法区等)、垃圾收集(GC)策略以及性能优化,对于提升Java程序的效率至关重要。了解JVM调优技巧,如...

    Jvm.rar_jni_jni 线程_jvm

    JNI的使用往往涉及到对JVM内部机制的了解,比如如何在本地代码中操作Java对象,管理Java的堆内存,以及处理线程同步问题。 "www.pudn.com.txt"这个文件可能是从网站www.pudn.com下载的资源说明或者示例代码的引用。...

    Java jvm虚拟机.zip

    了解JVM内部工作原理有助于识别和解决性能瓶颈,提高应用的响应速度和稳定性。 JVM还涉及到一些概念,如类加载双亲委派模型、异常处理、线程同步等。理解和掌握这些内容对于深入学习Java技术和提升编程能力至关重要...

    jvm内部结构大解密

    JVM 内部结构大解密 在 Java 虚拟机(JVM)中,数据类型可以分为两类:基本类型和引用类型。基本类型的变量保存原始值,即:他代表的值就是数值本身;而引用类型的变量保存引用值。“引用值”代表了某个对象的引用...

    jvm 详细介绍,了解jvm各个组成部分和功能

    ### JVM 详细介绍:掌握 JVM 的各个组成部分与功能 #### 一、Java 源文件编译及执行 Java 应用程序的核心...理解 JVM 的内部工作原理有助于开发者更好地编写高质量的 Java 应用程序,并有效解决运行时遇到的问题。

    JVM详解-淘宝内部资料

    Java虚拟机(JVM)是Java程序运行的核心,它是Java平台的一个重要组成部分。"JVM详解-淘宝内部资料"提供了一套深入理解JVM的资源,涵盖了从基础到高级的各种主题,包括Java虚拟机的生命周期、JVM的体系结构、各个...

    深入JVM内核 - 原理、诊断与优化

    介绍JVM的内部结构、启动流程以及内存模型。并介绍JVM字节码的执行方式。 第三课 常用JVM参数 堆的分配参数 栈分配及实例讲解 server与client模式 调试跟踪参数 介绍常用的JVM参数,包括内存分配、堆栈分配、...

    JVM01-课程介绍1

    JVM基础知识涵盖了其内部结构和工作原理,包括类加载机制、内存模型(JMM)以及Java字节码技术。类加载器是JVM如何找到并加载类的关键组件,而JMM则定义了在并发环境下共享数据的规则。Java字节码是Java源代码编译后...

    JVM虚拟机深度讲解

    7. 调试与诊断:了解JVM内部工作原理,有助于进行问题定位和性能调优。例如,使用JStack查看线程堆栈信息,JMap分析内存分配,Jhat进行堆转储分析等。 8. 其他高级特性:JVM还涉及模块系统、反射、动态类型语言支持...

    jvm特性与java特性

    2. 内存管理:JVM内部有一套完整的垃圾收集机制(Garbage Collection, GC),负责管理Java堆内存,自动进行内存分配和回收。垃圾收集可以极大地简化Java程序员的内存管理工作,减少内存泄漏和指针错误等常见问题。它...

Global site tag (gtag.js) - Google Analytics