JVM 自帶線程

一個JVM 啓動以後,本身會啓動一些線程。咱們在jstack的時候能夠排除掉這些。只關注咱們本身業務產生的線程java

代碼jvm

Java代碼   收藏代碼
  1. package com.cases;  
  2.   
  3. import java.lang.management.GarbageCollectorMXBean;  
  4. import java.lang.management.ManagementFactory;  
  5. import java.lang.management.MemoryMXBean;  
  6. import java.util.List;  
  7. import java.util.Map;  
  8.   
  9. public class Gouzi {  
  10.   
  11.     public static void main(String[] args) {  
  12.         jvmExitHook();  
  13.   
  14.         System.out.println("aaaa");  
  15.         try {  
  16.             Thread.sleep(10000);  
  17.         } catch (InterruptedException e) {  
  18.             e.printStackTrace();  
  19.         }  
  20.   
  21.         System.exit(0);  
  22.     }  
  23.   
  24.     public static void jvmExitHook() {  
  25.         System.out.println("註冊JVM Shutdown鉤子方法---------");  
  26.         Runtime.getRuntime().addShutdownHook(new Thread() {  
  27.             @Override  
  28.             public void run() {  
  29.                 MemoryMXBean memorymbean = ManagementFactory.getMemoryMXBean();  
  30.                 System.out.println("堆內存信息: " + memorymbean.getHeapMemoryUsage());  
  31.                 System.out.println("非堆內存信息: " + memorymbean.getNonHeapMemoryUsage());  
  32.                 Map<Thread, StackTraceElement[]> map = Thread.getAllStackTraces();  
  33.   
  34.                 List<GarbageCollectorMXBean> list = ManagementFactory.getGarbageCollectorMXBeans();  
  35.                 if (list != null && list.size() > 0) {  
  36.                     for (GarbageCollectorMXBean gcBean : list) {  
  37.                         System.out.println("垃圾收集器:" + gcBean.getName());  
  38.                         System.out.println("gc count:" + gcBean.getCollectionCount());  
  39.                         System.out.println("gc time:" + gcBean.getCollectionTime());  
  40.                         gcBean.getCollectionCount();  
  41.                     }  
  42.                 }  
  43.   
  44.                 for (Thread t : map.keySet()) {  
  45.                     System.out.println("線程名稱:" + t.getName() + ",線程堆棧:");  
  46.                     StackTraceElement[] ss = map.get(t);  
  47.                     if (ss != null) {  
  48.                         for (StackTraceElement s : ss) {  
  49.                             System.out.println(s);  
  50.                         }  
  51.                     }  
  52.                 }  
  53.             }  
  54.   
  55.         });  
  56.     }  
  57. }  

 

 

輸出結果ide

 

註冊JVM Shutdown鉤子方法---------spa

aaaa線程

內存信息: init = 16777216(16384K) used = 560368(547K) committed = 16252928(15872K) max = 259522560(253440K)htm

未使用內存信息: init = 35815424(34976K) used = 13675040(13354K) committed = 36110336(35264K) max = 123731968(120832K)對象

垃圾收集器:Copy內存

gc count:0rem

gc time:0get

垃圾收集器:MarkSweepCompact

gc count:0

gc time:0

線程名稱:Attach Listener,線程堆棧:

線程名稱:Finalizer,線程堆棧:

java.lang.Object.wait(Native Method)

java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)

java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134)

java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:171)

線程名稱:Signal Dispatcher,線程堆棧:

線程名稱:Reference Handler,線程堆棧:

java.lang.Object.wait(Native Method)

java.lang.Object.wait(Object.java:485)

java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116)

線程名稱:Thread-0,線程堆棧:

java.lang.Thread.dumpThreads(Native Method)

java.lang.Thread.getAllStackTraces(Thread.java:1530)

com.cases.Gouzi$1.run(Gouzi.java:32)

線程名稱:main,線程堆棧:

java.lang.Object.wait(Native Method)

java.lang.Thread.join(Thread.java:1186)

java.lang.Thread.join(Thread.java:1239)

java.lang.ApplicationShutdownHooks.runHooks(ApplicationShutdownHooks.java:79)

java.lang.ApplicationShutdownHooks$1.run(ApplicationShutdownHooks.java:24)

java.lang.Shutdown.runHooks(Shutdown.java:79)

java.lang.Shutdown.sequence(Shutdown.java:123)

java.lang.Shutdown.exit(Shutdown.java:168)

java.lang.Runtime.exit(Runtime.java:90)

java.lang.System.exit(System.java:904)

com.cases.Gouzi.main(Gouzi.java:21)

 

上邊main線程和Thread-0是我啓動的

 

Attach Listener

Finalizer

Signal Dispatcher

Reference Handler

是JVM 啓動的

 

下邊作一個解釋:

 

Attach Listener :線程是負責接收到外部的命令,而對該命令進行執行的而且吧結果返回給發送者。一般咱們會用一些命令去要求jvm給咱們一些反饋信息,如:java -version、jmap、jstack等等。若是該線程在jvm啓動的時候沒有初始化,那麼,則會在用戶第一次執行jvm命令時,獲得啓動。

 

signal dispather: 前面咱們提到第一個Attach Listener線程的職責是接收外部jvm命令,當命令接收成功後,會交給signal dispather線程去進行分發到各個不一樣的模塊處理命令,而且返回處理結果。signal dispather線程也是在第一次接收外部jvm命令時,進行初始化工做。

 

Finalizer:  用來執行全部用戶Finalizer 方法的線程

 

Reference Handler :它主要用於處理引用對象自己(軟引用、弱引用、虛引用)的垃圾回收問題。

 

 

在一些其餘場景Jvm會啓動更多的線程,能夠參考:http://club.alibabatech.org/article_detail.htm?articleId=4 

相關文章
相關標籤/搜索