我正在尝试了解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 = 143
的VM_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);
SIGTERM
, SIGINT
和 SIGHUP
在java.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]