其实这些内容有个名词叫做    JVM内部线程

下面我们对这些功能挨个解说

 JDK 版本:Java HotSpot(TM) 64-Bit Server VM (build 24.51-b03, mixed mode)

  下面的输出是一个典型的HotSpot JVM的thread dump,以此为例,来说明一下JVM的内部线程功能。

  2014-04-29 17:59:54

  Full thread dump Java HotSpot(TM) 64-Bit Server VM (24.51-b03 mixed mode):

  "Attach Listener" daemon prio=5 tid=0x00007fc6b6800800 nid=0x3b07 waiting on condition [0x0000000000000000]

  java.lang.Thread.State: RUNNABLE

  "DestroyJavaVM" prio=5 tid=0x00007fc6b3001000 nid=0x1903 waiting on condition [0x0000000000000000]

  java.lang.Thread.State: RUNNABLE

  "Service Thread" daemon prio=5 tid=0x00007fc6b3840000 nid=0x5303 runnable [0x0000000000000000]

  java.lang.Thread.State: RUNNABLE

  "C2 CompilerThread1" daemon prio=5 tid=0x00007fc6b280f800 nid=0x5103 waiting on condition [0x0000000000000000]

  java.lang.Thread.State: RUNNABLE

  "C2 CompilerThread0" daemon prio=5 tid=0x00007fc6b5035800 nid=0x4f03 waiting on condition [0x0000000000000000]

  java.lang.Thread.State: RUNNABLE

  "Signal Dispatcher" daemon prio=5 tid=0x00007fc6b502e000 nid=0x4d03 runnable [0x0000000000000000]

  java.lang.Thread.State: RUNNABLE

  "Finalizer" daemon prio=5 tid=0x00007fc6b2818800 nid=0x3903 in Object.wait() [0x000000011fda0000]

  java.lang.Thread.State: WAITING (on object monitor)

  at java.lang.Object.wait(Native Method)

  - waiting on <0x00000007000049a0> (a java.lang.ref.ReferenceQueue$Lock)

  at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:135)

  - locked <0x00000007000049a0> (a java.lang.ref.ReferenceQueue$Lock)

  at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:151)

  at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:189)

  "Reference Handler" daemon prio=5 tid=0x00007fc6b2815800 nid=0x3703 in Object.wait() [0x000000011fc9d000]

  java.lang.Thread.State: WAITING (on object monitor)

  at java.lang.Object.wait(Native Method)

  - waiting on <0x0000000700006b00> (a java.lang.ref.Reference$Lock)

  at java.lang.Object.wait(Object.java:503)

  at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:133)

  - locked <0x0000000700006b00> (a java.lang.ref.Reference$Lock)

  "VM Thread" prio=5 tid=0x00007fc6b383e800 nid=0x3503 runnable

  "GC task thread#0 (ParallelGC)" prio=5 tid=0x00007fc6b480d000 nid=0x2503 runnable

  "GC task thread#1 (ParallelGC)" prio=5 tid=0x00007fc6b2812000 nid=0x2703 runnable

  "GC task thread#2 (ParallelGC)" prio=5 tid=0x00007fc6b2812800 nid=0x2903 runnable

  "GC task thread#3 (ParallelGC)" prio=5 tid=0x00007fc6b2813000 nid=0x2b03 runnable

  "GC task thread#4 (ParallelGC)" prio=5 tid=0x00007fc6b2813800 nid=0x2d03 runnable

  "GC task thread#5 (ParallelGC)" prio=5 tid=0x00007fc6b2814800 nid=0x2f03 runnable

  "GC task thread#6 (ParallelGC)" prio=5 tid=0x00007fc6b2815000 nid=0x3103 runnable

  "GC task thread#7 (ParallelGC)" prio=5 tid=0x00007fc6b3801000 nid=0x3303 runnable

  "VM Periodic Task Thread" prio=5 tid=0x00007fc6b502f000 nid=0x5503 waiting on condition

  JNI global references: 159

  1. Attach Listener

  负责接收到外部的命令,而对该命令进行执行的并且吧结果返回给发送者。

  通常我们会用一些命令去要求jvm给我们一些反馈信息,如:java -version、jmap、jstack等等。 如果该线程在jvm启动的时候没有初始化,那么,则会在用户第一次执行jvm命令时,得到启动。

  2. DestroyJavaVM

  执行main()的线程在main执行完后调用JNI中的 jni_DestroyJavaVM() 方法唤起DestroyJavaVM 线程。

  JVM在 Jboss 服务器启动之后,就会唤起DestroyJavaVM线程,处于等待状态,等待其它线程(java线程和native线程)退出时通知它卸载JVM。线程退出时,都会判断自己当前是否是整个JVM中最后一个非deamon线程,如果是,则通知DestroyJavaVM 线程卸载JVM。

  (1)如果线程退出时判断自己不为最后一个非deamon线程,那么调用thread->exit(false) ,并在其中抛出thread_end事件,jvm不退出。

  (2)如果线程退出时判断自己为最后一个非deamon线程,那么调用before_exit() 方法,抛出两个事件:thread_end 线程结束事件和VM的death事件。

  然后调用thread->exit(true) 方法,接下来把线程从active list卸下,删除线程等等一系列工作执行完成后,则通知正在等待的DestroyJavaVM 线程执行卸载JVM操作。

  3. Service Thread

  4. CompilerThread0

  用来调用JITing,实时编译装卸CLASS。

  通常JVM会启动多个线程来处理这部分工作,线程名称后面的数字也会累加,比如CompilerThread1。

  5. Signal Dispatcher

  Attach Listener线程的职责是接收外部jvm命令,当命令接收成功后,会交给signal dispather 线程去进行分发到各个不同的模块处理命令,并且返回处理结果。

  signal dispather线程也是在第一次接收外部jvm命令时,进行初始化工作。

  6. Finalizer

  这个线程也是在main线程之后创建的,其优先级为10,主要用于在垃圾收集前,调用对象的finalize()方法;关于Finalizer线程的几点:

  (1)只有当开始一轮垃圾收集时,才会开始调用finalize()方法;因此并不是所有对象的finalize()方法都会被执行;

  (2)该线程也是daemon线程,因此如果虚拟机中没有其他非daemon线程,不管该线程有没有执行完finalize()方法,JVM也会退出;

  (3)JVM在垃圾收集时会将失去引用的对象包装成Finalizer对象(Reference的实现),并放入ReferenceQueue,由Finalizer线程来处理;最后将该Finalizer对象的引用置为null,由垃圾收集器来回收;

  (4)JVM为什么要单独用一个线程来执行finalize()方法呢?

  如果JVM的垃圾收集线程自己来做,很有可能由于在finalize()方法中误操作导致GC线程停止或不可控,这对GC线程来说是一种灾难。

  7. Reference Handler

  JVM在创建main线程后就创建Reference Handler线程,其优先级最高,为10,它主要用于处理引用对象本身(软引用、弱引用、虚引用)的垃圾回收问题 。

  8. VM Thread

  这个线程比较牛,是JVM里面的线程母体,根据hotspot源码:vmThread.hpp里面的注释,它是一个单例的对象(最原始的线程)会产生或触发所有其他的线程,这个单个的VM线程是会被其他线程所使用来做一些VM操作(如清扫垃圾等)。

  在 VM Thread 的结构体里有一个VMOperationQueue列队,所有的VM线程操作(vm_operation)都会被保存到这个列队当中,VMThread 本身就是一个线程,它的线程负责执行一个自轮询的loop函数(具体可以参考:VMThread.cpp里面的void VMThread::loop()) ,该loop函数从VMOperationQueue列队中按照优先级取出当前需要执行的操作对象(VM_Operation),并且调用VM_Operation->evaluate函数去执行该操作类型本身的业务逻辑。

  VM操作类型被定义在vm_operations.hpp文件内,列举几个:ThreadStop、ThreadDump、PrintThreads、GenCollectFull、GenCollectFullConcurrent、CMS_Initial_Mark、CMS_Final_Remark….. 有兴趣的同学,可以自己去查看源文件。

  9. GC task thread#0 (ParallelGC)

  垃圾回收线程,负责垃圾回收。

  通常JVM会启动多个线程来处理这部分工作,线程名称中#后面的数字也会累加,比如GC task thread#1 (ParallelGC)。

  10. VM Periodic Task Thread

  该线程是JVM周期性任务调度的线程,它由WatcherThread创建,是一个单例对象。

  该线程在JVM内使用得比较频繁,比如:定期的内存监控、JVM运行状况监控。

  可以使用jstat 命令查看GC的情况,比如查看某个进程没有存活必要的引用:

  jstat -gcutil 23483 250 7

  让JVM在控制台输出pid=23483的没有存活必要的引用情况,间隔250毫秒打印一次,一共打印7次。

  这对于防止因为应用代码中直接使用native库或者第三方的一些监控工具的内存泄漏有非常大的帮助。

  11. JNI (Java Native Interface) global reference count

  全局引用也是受垃圾回收器管理。

  它的作用是防止回收到那些在native代码上还是被引用的,但是在java代码中却没有存活必要的引用。

  对于防止因为应用代码中直接使用native库或者第三方的一些监控工具的内存泄漏有非常大的帮助。

  如果启动Java程序时,增加了参数:-XX:+UseConcMarkSweepGC,表明将启用CMS (Concurrent Mark-Sweep)GC Thread,下面就是设置CMS GC后的thread dump:

  2014-04-30 11:52:02

  Full thread dump Java HotSpot(TM) 64-Bit Server VM (24.51-b03 mixed mode):

  "Attach Listener" daemon prio=5 tid=0x00007fb6838bf000 nid=0x4a0b waiting on condition [0x0000000000000000]

  java.lang.Thread.State: RUNNABLE

  "DestroyJavaVM" prio=5 tid=0x00007fb683945000 nid=0x1903 waiting on condition [0x0000000000000000]

  java.lang.Thread.State: RUNNABLE

  "Service Thread" daemon prio=5 tid=0x00007fb682821000 nid=0x5b03 runnable [0x0000000000000000]

  java.lang.Thread.State: RUNNABLE

  "C2 CompilerThread1" daemon prio=5 tid=0x00007fb682834800 nid=0x5903 waiting on condition [0x0000000000000000]

  java.lang.Thread.State: RUNNABLE

  "C2 CompilerThread0" daemon prio=5 tid=0x00007fb6838c7000 nid=0x5703 waiting on condition [0x0000000000000000]

  java.lang.Thread.State: RUNNABLE

  "Signal Dispatcher" daemon prio=5 tid=0x00007fb683001000 nid=0x5503 runnable [0x0000000000000000]

  java.lang.Thread.State: RUNNABLE

  "Surrogate Locker Thread (Concurrent GC)" daemon prio=5 tid=0x00007fb6838bd000 nid=0x521f waiting on condition [0x0000000000000000]

  java.lang.Thread.State: RUNNABLE

  "Finalizer" daemon prio=5 tid=0x00007fb6838bc800 nid=0x3f03 in Object.wait() [0x0000000111e4c000]

  java.lang.Thread.State: WAITING (on object monitor)

  at java.lang.Object.wait(Native Method)

  - waiting on <0x00000007247b8780> (a java.lang.ref.ReferenceQueue$Lock)

  at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:135)

  - locked <0x00000007247b8780> (a java.lang.ref.ReferenceQueue$Lock)

  at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:151)

  at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:189)

  "Reference Handler" daemon prio=5 tid=0x00007fb68300f000 nid=0x3d03 in Object.wait() [0x0000000111d49000]

  java.lang.Thread.State: WAITING (on object monitor)

  at java.lang.Object.wait(Native Method)

  - waiting on <0x00000007247b0830> (a java.lang.ref.Reference$Lock)

  at java.lang.Object.wait(Object.java:503)

  at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:133)

  - locked <0x00000007247b0830> (a java.lang.ref.Reference$Lock)

  "VM Thread" prio=5 tid=0x00007fb68403c800 nid=0x3b03 runnable

  "Gang worker#0 (Parallel GC Threads)" prio=5 tid=0x00007fb683800000 nid=0x2503 runnable

  "Gang worker#1 (Parallel GC Threads)" prio=5 tid=0x00007fb683801000 nid=0x2703 runnable

  "Gang worker#2 (Parallel GC Threads)" prio=5 tid=0x00007fb68281e800 nid=0x2903 runnable

  "Gang worker#3 (Parallel GC Threads)" prio=5 tid=0x00007fb683801800 nid=0x2b03 runnable

  "Gang worker#4 (Parallel GC Threads)" prio=5 tid=0x00007fb683002000 nid=0x2d03 runnable

  "Gang worker#5 (Parallel GC Threads)" prio=5 tid=0x00007fb683003000 nid=0x2f03 runnable

  "Gang worker#6 (Parallel GC Threads)" prio=5 tid=0x00007fb683003800 nid=0x3103 runnable

  "Gang worker#7 (Parallel GC Threads)" prio=5 tid=0x00007fb683802000 nid=0x3303 runnable

  "Concurrent Mark-Sweep GC Thread" prio=5 tid=0x00007fb6838ba000 nid=0x3903 runnable

  "Gang worker#0 (Parallel CMS Threads)" prio=5 tid=0x00007fb6838b8800 nid=0x3503 runnable

  "Gang worker#1 (Parallel CMS Threads)" prio=5 tid=0x00007fb6838b9000 nid=0x3703 runnable

  "VM Periodic Task Thread" prio=5 tid=0x00007fb682820000 nid=0x5d03 waiting on condition

  JNI global references: 159

  可以看出,多了以下线程:

  12. Concurrent Mark-Sweep GC Thread

  并发标记清除垃圾回收器(就是通常所说的CMS GC)线程, 该线程主要针对于年老代垃圾回收。

  13. Surrogate Locker Thread (Concurrent GC)

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

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

  (2)WeakHashMap的Entry比较特殊,它的继承体系结构为Entry->WeakReference->Reference 。

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

  (4)Reference 里面有一个静态变量:pending。

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

  (6)另外,WeakHashMap里面还实例化了一个ReferenceQueue列队,这个列队的作用,后面会提到。

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

  假设,WeakHashMap对象里面已经保存了很多对象的引用。 JVM 在进行CMS GC的时候,会创建一个ConcurrentMarkSweepThread(简称CMST)线程去进行GC,ConcurrentMarkSweepThread线程被创建的同时会创建一个SurrogateLockerThread(简称SLT)线程并且启动它,SLT启动之后,处于等待阶段。CMST开始GC时,会发一个消息给SLT让它去获取Java层Reference对象的全局锁:Lock。 直到CMS GC完毕之后,JVM 会将WeakHashMap中所有被回收的对象所属的WeakReference容器对象放入到Reference 的pending属性当中(每次GC完毕之后,pending属性基本上都不会为null了),然后通知SLT释放并且notify全局锁:Lock。此时激活了ReferenceHandler线程的run方法,使其脱离wait状态,开始工作了。ReferenceHandler这个线程会将pending中的所有WeakReference对象都移动到它们各自的列队当中,比如当前这个WeakReference属于某个WeakHashMap对象,那么它就会被放入相应的ReferenceQueue列队里面(该列队是链表结构)。 当我们下次从WeakHashMap对象里面get、put数据或者调用size方法的时候,WeakHashMap就会将ReferenceQueue列队中的WeakReference依依poll出来去和Entry[]数据做比较,如果发现相同的,则说明这个Entry所保存的对象已经被GC掉了,那么将Entry[]内的Entry对象剔除掉。

  14. 原来的垃圾回收线程GC task thread#0 (ParallelGC) 被替换为 Gang worker#0 (Parallel GC Threads)

  垃圾回收线程,负责垃圾回收。

  通常JVM会启动多个线程来处理这部分工作,线程名称中#后面的数字也会累加,比如GC task thread#1 (Parallel GC Threads)。

  Gang worker 是JVM用于做年轻代垃圾回收(minor gc)的线程。

jstack -l pid 内容解析相关推荐

  1. jstack -l pid:查看线程状态,使用的垃圾回收算法,死锁检测

    先jps查看java应用相关id: [quote] C:\Users\Administrator>jps 9712 Bootstrap 6628 8584 Jps 7900 8780 Serve ...

  2. 路漫漫其修远矣 - 关于内容解析 与 存储

    用scrapy框架后,很多访问问题解决了,css解析也非常方便,于是要将之前关注的一个网站爬下来放到mysql里面,然后用tableau接上,这样就可以长期自动监测了.但过程非常坎坷,一直到现在也没有 ...

  3. 2020-11-12(内容提供者,内容解析者,内容观察者)

    内容提供者实现步骤 a.写一个类继承ContentProvider 重写onCreat query delete insert getType b.在清单文件中声明对应的provider节点 auth ...

  4. resource.arsc二进制内容解析 之 Dynamic package reference

    目录 1.加载Theme出错 2.aapt中的特殊处理 3.RES_TABLE_LIBRARY_TYPE 4.dynamicRefTable位置 5.验证dynamicRefTable 6.总结 1. ...

  5. resource.arsc二进制内容解析 之 RES_TABLE_TYPE_TYPE (Config List)

    目录 1.resource.arsc结构 2.RES_TABLE_TYPE_TYPE 3.ResTable_type 4.ResTable_entry偏移数组 5.ResTable_entry(非ba ...

  6. YOLOv2-darknet 内容解析

    目录 YOLOv2-darknet 内容解析 1. 改进之处 2. Better 3. Faster 4. Stronger 5. 总结 reference YOLOv2-darknet 内容解析 1 ...

  7. gradle相关配置内容解析

    gradle 项目的构建工具,基于groovy语言.主要用于管理依赖包. as中一般将gradle下载在C:\Documents and Settings<用户名>.gradle\wrap ...

  8. bam文件读取_SAM/BAM 格式文件内容解析

    一.首先需要知道以下几个知识点: 1.1-based coordinate system A coordinate system where the rst base of a sequence is ...

  9. mt950报文解析_系列之五 | MT759报文升级内容解析

    根据SWIFT组织2018至2019年对SWIFT报文格式的升级安排,2018年11月18日信用证相关报文的升级新增了MT744.MT759和MT708三种报文,其中MT759报文为标准化.格式化的自 ...

最新文章

  1. nginx不同server不同日志文件_招标里的答疑是什么?和澄清文件有何不同?
  2. 分布式缓存的选择及问题
  3. python实现pdf转word详解_手把手|20行Python代码教你批量将PDF文件转为Word格式(包教包会)...
  4. 「C++」C++ Primer Plus 笔记:第十七章 输入、输出和文件
  5. java cookie id,我如何在Java中获取会话ID
  6. c#制作飘动动画窗体
  7. c语言 字符串字符反向储存_C ++中的反向字符串
  8. oracle日期处理函数
  9. 无约束最优化(三) 拟Newton法
  10. 二维数组矩阵常用实现方法
  11. 【LaTex】Vscode+LaTex模板的使用
  12. 双向晶闸管,调压电路,开关电路,楼梯灯电路,光控路灯,无电弧接触器电路
  13. #######好好好好##########知识图谱商业应用
  14. 最佳实践:银尔达YED-S724 网红4G DTU 接入 ThingsKit 物联网平台
  15. Excel:删除一列中的重复值
  16. 捷普服务器群组防护系统,捷普入侵防御系统
  17. signature=1786f140adeed932d2fada45ef17913d,PENGARUH ADITIF BAHAN BAKAR DIESEL PADA OPERASI STASIONER
  18. 线性表、树形结构和图形结构的区别
  19. 计算机视觉图像处理入门
  20. linux中测端口通讯nc,linux命令之 - nc 测试端口的连通

热门文章

  1. Cerebral Cortex:老年人生活方式与脑功能连接的关系及其与认知能力下降的联系
  2. 如何统一修改标注文字的颜色和大小?
  3. OOP基础 、 OOP进阶 、 re模块案例
  4. 【深度首发】eyemore能否成为AI时代的“索尼”?丨Xtecher 封面
  5. Python3_爬虫实践(爬取电子书)
  6. Centos配置IP地址
  7. windows下搭建syslog服务器及基本配置
  8. 会议平板同质化,行业领航者MAXHUB如何打破僵局?
  9. U盘一般有三种常见的格式:FAT32,NTFS和exFAT
  10. 程序员也有情,攻城狮也有爱