在发送Sigterm和谁进行交付时,如何将VM_EXIT传递到VM线程



我正在尝试了解JVM热点如何处理终止信号(例如SIGTERM(。我能发现的是,SIGTERM信号处置在此时将其设置为UserHandler,它看起来像(注释(:

static void UserHandler(int sig, void *siginfo, void *context) {
  if (sig == SIGINT && Atomic::add(1, &sigint_count) > 1) {
    return;
  }
  if (sig == SIGINT && VMError::is_error_reported()) {
    os::die();
  }
  os::signal_notify(sig);
}

因此,它所做的就是通知Signal Dispatcher并将接收的信号编号设置为static volatile jint pending_signals[NSIG+1]

但是,在SIGTERM的情况下,实际exit(143)是在VM Thread中完成的。使用_exit_code = 143VM_Exit任务以某种方式交付给VM Thread

问题:您可以给出一个提示谁生成此VM_Exit任务并稍后将其发送到VM Thread?我特别担心143设置为VM_Exit::_exit_code

我在GDB下运行了JVM热点,并带有以下主要类:

public class Main{
    public static void main(String args[]) throws Exception {
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            System.out.println("Shutdown hook is called");
        }));
        Thread.sleep(1000000);
    }
}

并且没有发现Signal Dispatcher正在发送VM_Exit任务。终止在该声明中发生:

JavaCalls::call_virtual(&result,
                        threadObj, thread_klass,
                        vmSymbols::exit_method_name(),
                        vmSymbols::void_method_signature(),
                        THREAD);

SIGTERMSIGINTSIGHUPjava.lang.Terminator的Java代码中处理。

异步 - 螺旋形的鲜为人知的特征之一是它可以配置任意本机函数并显示混合的Java 本机堆栈。例如。如果要拦截JVM_Halt并查看Java代码称之为什么,请运行

$ java -agentpath:/path/to/libasyncProfiler.so=start,traces,threads,event=JVM_Halt Main
Started [JVM_Halt] profiling
^CShutdown hook is called
--- 1 events (100.00%), 1 sample
  [ 0] JVM_Halt
  [ 1] java.lang.Shutdown.halt0
  [ 2] java.lang.Shutdown.halt
  [ 3] java.lang.Shutdown.exit
  [ 4] java.lang.Terminator$1.handle
  [ 5] jdk.internal.misc.Signal$1.run
  [ 6] java.lang.Thread.run
  [ 7] [SIGINT handler tid=19080]

最新更新