JVM线程

JVM线程

参考《Java内存泄漏分析系列》

dump文件结构

属性含义

"http-nio-9090-exec-2"      线程名称
prio                        优先级
os_prio                     系统优先级
tid                         虚拟机中的Java线程id
nid                         线程在操作系统中的id
[0x00007f5822648000]        线程栈起始内存地址

Identifier & Version

2018-06-15 01:12:34
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.144-b01 mixed mode):

Application Threads

"http-nio-9090-exec-2" #38 daemon prio=5 os_prio=0 tid=0x00007f592b133800 nid=0xacc6 waiting on condition [0x00007f5822648000]
   java.lang.Thread.State: WAITING (parking)
	at sun.misc.Unsafe.park(Native Method)
	- parking to wait for  <0x000000076b27c218> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
	at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
	at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
	at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:103)
	at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
	at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:748)

VM Threads

JVM 内部运行线程介绍

VM Thread,负责创建其它所有线程,并通过自轮询VMOperationQueue,按照优先级执行VM_Operation,例如ThreadDump、CMS_Initial_Mark。

"VM Thread" os_prio=0 tid=0x00007f59283c6000 nid=0xac91 runnable

Attach Listener,负责处理JVM外部的命令,如jstack,在第一次执行JVM命令时启动。

"Attach Listener" #54 daemon prio=9 os_prio=0 tid=0x00007f589c001000 nid=0xae90 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

Signal Dispatcher,负责分发Attach Listener接收到的命令,第一次分发时启动。

"Signal Dispatcher" #4 daemon prio=9 os_prio=0 tid=0x00007f5928405000 nid=0xac94 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

DestroyJavaVM,负责卸载JVM。

"DestroyJavaVM" #52 prio=5 os_prio=0 tid=0x00007f5928008800 nid=0xac78 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

Service Thread,用于启动服务的线程。

"Service Thread" #20 daemon prio=9 os_prio=0 tid=0x00007f5928431800 nid=0xaca4 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

CompilerThread,实时编译装卸class,可能会造成CPU抖动

"C1 CompilerThread14" #19 daemon prio=9 os_prio=0 tid=0x00007f5928426000 nid=0xaca3 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

Finalizer,负责在垃圾回收前调用对象的finalize()方法。JVM将失去引用的对象包装成Finalizer对象(Reference的实现),放入ReferenceQueue,由Finalizer线程处理。

"Finalizer" #3 daemon prio=8 os_prio=0 tid=0x00007f59283d2000 nid=0xac93 in Object.wait() [0x00007f58ddedd000]
   java.lang.Thread.State: WAITING (on object monitor)
	at java.lang.Object.wait(Native Method)
	- waiting on <0x000000068782bac0> (a java.lang.ref.ReferenceQueue$Lock)
	at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
	- locked <0x000000068782bac0> (a java.lang.ref.ReferenceQueue$Lock)
	at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)
	at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)

Reference Handler,优先级最高,负责处理引用对象本身的垃圾回收问题。

"Reference Handler" #2 daemon prio=10 os_prio=0 tid=0x00007f59283cd800 nid=0xac92 in Object.wait() [0x00007f58ddfde000]
   java.lang.Thread.State: WAITING (on object monitor)
	at java.lang.Object.wait(Native Method)
	- waiting on <0x000000068782bab0> (a java.lang.ref.Reference$Lock)
	at java.lang.Object.wait(Object.java:502)
	at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
	- locked <0x000000068782bab0> (a java.lang.ref.Reference$Lock)
	at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)

GC Thread

GC task thread,GC线程,创建后会一直复用,逻辑CPU不大于8时,线程数量为CPU数,否则为8 + ( ncpus - 8 ) * 5/8线程数逻辑

"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00007f592801e000 nid=0xac79 runnable 
unsigned int Abstract_VM_Version::calc_parallel_worker_threads() {
  return nof_parallel_worker_threads(5, 8, 8);
}

unsigned int Abstract_VM_Version::nof_parallel_worker_threads(
                                                      unsigned int num,
                                                      unsigned int den,
                                                      unsigned int switch_pt) {
  if (FLAG_IS_DEFAULT(ParallelGCThreads)) {
    assert(ParallelGCThreads == 0, "Default ParallelGCThreads is not 0");
    // For very large machines, there are diminishing returns
    // for large numbers of worker threads.  Instead of
    // hogging the whole system, use a fraction of the workers for every
    // processor after the first 8.  For example, on a 72 cpu machine
    // and a chosen fraction of 5/8
    // use 8 + (72 - 8) * (5/8) == 48 worker threads.
    unsigned int ncpus = (unsigned int) os::initial_active_processor_count();
    return (ncpus <= switch_pt) ?
           ncpus :
          (switch_pt + ((ncpus - switch_pt) * num) / den);
  } else {
    return ParallelGCThreads;
  }
}

[虚拟机stack全分析]

以下摘录这篇博客的部分描述,对于回过头来理清概念比较重要。

VM是加载并执行字节码的机器,这个处理不对应具体硬件,它完全由软件来实现。虚拟机并不是直接跑在宿主的cpu上,中间还隔着宿主的操作系统。

虚拟机的职责是:翻译字节码,把它翻译成一系列的动作(内存操作)和系统调用(比如输入输出)。

举个例子:当在java里请求与某台远程机器建立socket连接时,java虚拟机本身是不能完成这一工作的(协议栈是在操作系统内实现的),所以它需要系统调用。

要明白这个,还需要知道JRE和JVM的关系。JRE是JVM的环境,一个应用程序就是一个JVM实例。

一个机器上一般同时只有一个JRE环境,但是可以同时有多个JVM实例

不同的操作系统和CPU架构有不同的JRE。JRE包含了最基本的类库,当然包括和操作系统打交道的Native库,比如windows下的dll文件,linux下的so文件。

JVM实例解析字节码的成JVM中的指令集,再通过Native方法进行操作系统层面的系统调用。下面的图能比较清楚的说明问题。

转载于:https://my.oschina.net/u/3035165/blog/1831523

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值