How to Safely Use Java Shutdown Hooks to Clean Up Resources on JVM Exit

This article explains the purpose and inner workings of Java's Runtime.addShutdownHook, walks through the Runtime and ApplicationShutdownHooks source code, demonstrates practical usage with examples, discusses common scenarios, potential risks, and best‑practice solutions for reliable resource cleanup during JVM shutdown.

JD Cloud Developers
JD Cloud Developers
JD Cloud Developers
How to Safely Use Java Shutdown Hooks to Clean Up Resources on JVM Exit

1. Question

How can we perform actions such as closing remote connections when the JVM exits?

2. Introduction to ShutdownHook

Java provides the method Runtime.getRuntime().addShutdownHook to register a shutdown hook. A shutdown hook is essentially a thread that the JVM starts during its shutdown sequence.

1. Runtime Class

Inspecting the source of Runtime reveals the addShutdownHook method.

1.1 Method Explanation

The JVM triggers registered shutdown hooks when it shuts down, either because the last non‑daemon thread exits, System.exit is called, or a user/system interrupt occurs.

Registers a new virtual‑machine shutdown hook
The Java virtual machine shuts down in response to two kinds of events:
- The program exits normally, when the last non‑daemon thread exits or when System.exit is invoked.
- The virtual machine is terminated in response to a user interrupt (e.g., ^C) or a system‑wide event such as user logoff or system shutdown.
A shutdown hook is simply an initialized but unstarted thread. When the virtual machine begins its shutdown sequence it will start all registered shutdown hooks in some unspecified order and let them run concurrently.
When all the hooks have finished it will then halt. Daemon threads continue to run during the shutdown sequence, as will non‑daemon threads if shutdown was initiated by invoking the exit method.

1.2 Method Source Code

public void addShutdownHook(Thread hook) {
    @SuppressWarnings("removal")
    SecurityManager sm = System.getSecurityManager();
    if (sm != null) {
        sm.checkPermission(new RuntimePermission("shutdownHooks"));
    }
    ApplicationShutdownHooks.add(hook);
}

The method internally calls ApplicationShutdownHooks.add.

2. ApplicationShutdownHooks Class

2.1 Adding a Hook

private static IdentityHashMap<Thread, Thread> hooks;
static synchronized void add(Thread hook) {
    if (hooks == null) throw new IllegalStateException("Shutdown in progress");
    if (hook.isAlive()) throw new IllegalArgumentException("Hook already running");
    if (hooks.containsKey(hook)) throw new IllegalArgumentException("Hook previously registered");
    hooks.put(hook, hook);
}

After adding a hook (a thread), the JVM will later execute it via runHooks.

2.2 Executing Hooks

static void runHooks() {
    Collection<Thread> threads;
    synchronized (ApplicationShutdownHooks.class) {
        threads = hooks.keySet();
        hooks = null;
    }
    for (Thread hook : threads) {
        hook.start();
    }
    for (Thread hook : threads) {
        while (true) {
            try {
                hook.join();
                break;
            } catch (InterruptedException ignored) {}
        }
    }
}

During runHooks, all registered hook threads are started and the JVM waits for each to finish.

2.3 Execution Timing

The shutdown sequence follows this call chain:

System.exit → Runtime.exit → Shutdown → runHooks → ApplicationShutdownHooks.runHooks → start hook threads.

3. Example

Below is a simple program that registers a shutdown hook which prints a message when the JVM terminates.

public static void main(String[] args) throws InterruptedException {
    Thread thread = new Thread() {
        @Override
        public void run() {
            System.out.println("Waiting for me");
        }
    };
    Runtime.getRuntime().addShutdownHook(thread);
    System.out.println("Program ending");
}

Output:

Program ending
Waiting for me

4. Application Scenarios

Typical uses include closing connections, stopping threads, releasing resources, and recording execution state before the JVM shuts down.

5. Risks

5.1 Long‑Running Hooks

If a hook thread runs for a long time, the JVM will wait for it, delaying shutdown. For example, a hook that sleeps for several minutes will cause the shutdown command to block until it finishes.

public static void main(String[] args) throws InterruptedException {
    Thread thread = new Thread() {
        @Override
        public void run() {
            try {
                Thread.sleep(1000 * 300);
            } catch (InterruptedException e) { e.printStackTrace(); }
            System.out.println(new Date() + " Waiting 5 minutes");
        }
    };
    Runtime.getRuntime().addShutdownHook(thread);
    System.out.println(new Date() + " Program closing");
}

5.2 Cause

The JVM invokes ApplicationShutdownHooks.runHooks during exit, and each hook thread is joined via hook.join(), causing the main thread to wait.

5.3 Solutions

Control the execution logic and duration of hook code.

Use forced termination (e.g., kill -9) if necessary.

6. Extensions

Many frameworks leverage addShutdownHook for resource cleanup. For instance, Spring registers shutdown hooks, and the @PreDestroy annotation triggers cleanup before bean destruction.

7. Summary

1) This article introduced the purpose, implementation, and risks of Java shutdown hooks.

2) In practice you can register your own hooks to proactively release resources and reduce shutdown‑related risks.

3) Feel free to share feedback and discuss other Java topics.

Join technical group QR code
Join technical group QR code
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

BackendJVMShutdownHookresource-management
JD Cloud Developers
Written by

JD Cloud Developers

JD Cloud Developers (Developer of JD Technology) is a JD Technology Group platform offering technical sharing and communication for AI, cloud computing, IoT and related developers. It publishes JD product technical information, industry content, and tech event news. Embrace technology and partner with developers to envision the future.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.