Ever wondered how a JVM reacts to various kill signals? The (intended) behaviour might be documented somewhere already, but I found having a table of the actual behaviour available quite useful. In particular I wanted to know which kill signals trigger the JVM to run registered shutdown hooks, and which kill signals don't actually terminate the JVM. So I decided to compile a table of that information.
I wrote up a small Java application that just registers a shutdown hook that I can detect whether it has executed or not, and then sleeps until I get a chance to kill it:
class Death {
public static void main(String... args) throws Exception {
Runtime.getRuntime().addShutdownHook( new Thread(){
@Override
public void run()
{
System.out.println("Shutting down");
}
} );
for (;;) Thread.sleep(100);
}
}
Then I ran the program in one terminal window (java Death; echo $?
) while iterating through all kill signals (0-31) in another:
kill -$SIGNAL $(jps | grep Death | cut -d\ -f1)
signal | shutdown | runs hook | exit code | comment |
---|---|---|---|---|
default (15) | yes | yes | 143 | SIGTERM is the default unix kill signal |
0 | no | - | - | |
1 (SIGHUP) | yes | yes | 129 | |
2 (SIGINT) | yes | yes | 130 | SIGINT is the signal sent on ^C |
3 (SIGQUIT) | no | - | - | Makes the JVM dump threads / stack-traces |
4 (SIGILL) | yes | no | 134 | Makes the JVM write a core dump and abort on trap 6 |
5 | yes | no | 133 | Makes the JVM exit with "Trace/BPT trap: 5" |
6 (SIGABRT) | yes | no | 134 | Makes the JVM exit with "Abort trap: 6" |
7 | yes | no | 135 | Makes the JVM exit with "EMT trap: 7" |
8 (SIGFPE) | yes | no | 134 | Makes the JVM write a core dump and abort on trap 6 |
9 (SIGKILL) | yes | no | 137 | The JVM is forcibly killed (exits with "Killed: 9") |
10 (SIGBUS) | yes | no | 134 | Emulates a "Bus Error" |
11 (SIGSEGV) | yes | no | 134 | Emulates a "Segmentation fault" |
12 | yes | no | 140 | Makes the JVM exit with "Bad system call: 12" |
13 | no | - | - | |
14 | yes | no | 142 | Makes the JVM exit with "Alarm clock: 14" |
15 (SIGTERM) | yes | yes | 143 | This is the default unix kill signal |
16 | no | - | - | |
17 | no | - | 145 | Stops the application (sends it to the background), same as ^Z |
18 | no | - | 146 | Stops the application (sends it to the background), same as ^Z |
19 | no | - | - | |
20 | no | - | - | |
21 | no | - | 149 | Stops the application (sends it to the background), same as ^Z |
22 | no | - | 150 | Stops the application (sends it to the background), same as ^Z |
23 | no | - | - | |
24 | yes | no | 152 | Makes the JVM exit with "Cputime limit exceeded: 24" |
25 | no | - | - | |
26 | yes | no | 154 | Makes the JVM exit with "Virtual timer expired: 26" |
27 | yes | no | 155 | Makes the JVM exit with "Profiling timer expired: 27" |
28 | no | - | - | |
29 | no | - | - | |
30 | yes | no | 158 | Makes the JVM exit with "User defined signal 1: 30" |
31 | yes | no | 134 | Makes the JVM exit on Segmentation fault |
This list was compiled using (a quite old) Oracle Hotspot Java 8 EA on Mac OS X:
java version "1.8.0-ea"
Java(TM) SE Runtime Environment (build 1.8.0-ea-b65)
Java HotSpot(TM) 64-Bit Server VM (build 25.0-b09, mixed mode)
Hope this is useful to more people than myself.