歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Java 工具(jmap,jstack)在Linux上的源碼分析(二)信號處理

Java 工具(jmap,jstack)在Linux上的源碼分析(二)信號處理

日期:2017/3/1 10:40:28   编辑:Linux編程

當java虛擬機啟動的時候,會啟動很多內部的線程,這些線程主要在thread.cpp裡的create_vm方法體裡實現

而在thread.cpp裡主要起了2個線程來處理信號相關的

  1. JvmtiExport::enter_live_phase();
  2. // Signal Dispatcher needs to be started before VMInit event is posted
  3. os::signal_init();
  4. // Start Attach Listener if +StartAttachListener or it can't be started lazily
  5. if (!DisableAttachMechanism) {
  6. if (StartAttachListener || AttachListener::init_at_startup()) {
  7. AttachListener::init();
  8. }
  9. }

1. Signal Dispatcher 線程

在os.cpp中的signal_init()函數中,啟動了signal dispatcher 線程,對signal dispather 線程主要是用於處理信號,等待信號並且分發處理,可以詳細看signal_thread_entry的方法

  1. static void signal_thread_entry(JavaThread* thread, TRAPS) {
  2. os::set_priority(thread, NearMaxPriority);
  3. while (true) {
  4. int sig;
  5. {
  6. // FIXME : Currently we have not decieded what should be the status
  7. // for this java thread blocked here. Once we decide about
  8. // that we should fix this.
  9. sig = os::signal_wait();
  10. }
  11. if (sig == os::sigexitnum_pd()) {
  12. // Terminate the signal thread
  13. return;
  14. }
  15. switch (sig) {
  16. case SIGBREAK: {
  17. // Check if the signal is a trigger to start the Attach Listener - in that
  18. // case don't print stack traces.
  19. if (!DisableAttachMechanism && AttachListener::is_init_trigger()) {
  20. continue;
  21. }
  22. // Print stack traces
  23. // Any SIGBREAK operations added here should make sure to flush
  24. // the output stream (e.g. tty->flush()) after output. See 4803766.
  25. // Each module also prints an extra carriage return after its output.
  26. VM_PrintThreads op;
  27. VMThread::execute(&op);
  28. VM_PrintJNI jni_op;
  29. VMThread::execute(&jni_op);
  30. VM_FindDeadlocks op1(tty);
  31. VMThread::execute(&op1);
  32. Universe::print_heap_at_SIGBREAK();
  33. if (PrintClassHistogram) {
  34. VM_GC_HeapInspection op1(gclog_or_tty, true /* force full GC before heap inspection */,
  35. true /* need_prologue */);
  36. VMThread::execute(&op1);
  37. }
  38. if (JvmtiExport::should_post_data_dump()) {
  39. JvmtiExport::post_data_dump();
  40. }
  41. break;
  42. }
  43. default: {
  44. // Dispatch the signal to java
  45. HandleMark hm(THREAD);
  46. klassOop k = SystemDictionary::resolve_or_null(vmSymbolHandles::sun_misc_Signal(), THREAD);
  47. KlassHandle klass (THREAD, k);
  48. if (klass.not_null()) {
  49. JavaValue result(T_VOID);
  50. JavaCallArguments args;
  51. args.push_int(sig);
  52. JavaCalls::call_static(
  53. &result,
  54. klass,
  55. vmSymbolHandles::dispatch_name(),
  56. vmSymbolHandles::int_void_signature(),
  57. &args,
  58. THREAD
  59. );
  60. }
  61. if (HAS_PENDING_EXCEPTION) {
  62. // tty is initialized early so we don't expect it to be null, but
  63. // if it is we can't risk doing an initialization that might
  64. // trigger additional out-of-memory conditions
  65. if (tty != NULL) {
  66. char klass_name[256];
  67. char tmp_sig_name[16];
  68. const char* sig_name = "UNKNOWN";
  69. instanceKlass::cast(PENDING_EXCEPTION->klass())->
  70. name()->as_klass_external_name(klass_name, 256);
  71. if (os::exception_name(sig, tmp_sig_name, 16) != NULL)
  72. sig_name = tmp_sig_name;
  73. warning("Exception %s occurred dispatching signal %s to handler"
  74. "- the VM may need to be forcibly terminated",
  75. klass_name, sig_name );
  76. }
  77. CLEAR_PENDING_EXCEPTION;
  78. }
  79. }
  80. }
  81. }
  82. }

可以看到通過os::signal_wait();等待信號,而在linux裡是通過sem_wait()來實現,接受到SIGBREAK(linux 中的QUIT)信號的時候(關於信號處理請參考筆者的另一篇:Java 中關於信號的處理在Linux下的實現 http://www.linuxidc.com/Linux/2012-01/51212.htm),第一次通過調用 AttachListener::is_init_trigger()初始化attach listener線程,詳細見2.Attach Listener 線程。

  1. 第一次收到信號,會開始初始化,當初始化成功,將會直接返回,而且不返回任何線程stack的信息(通過socket file的操作返回),並且第二次將不在需要初始化。如果初始化不成功,將直接在控制台的outputstream中打印線程棧信息。
  2. 第二次收到信號,如果已經初始化過,將直接在控制台中打印線程的棧信息。如果沒有初始化,繼續初始化,走和第一次相同的流程。
Copyright © Linux教程網 All Rights Reserved