Will a JVM Exit When a Thread Runs Out of Memory? Deep Dive with Code

This article investigates whether the JVM terminates when a thread encounters an OutOfMemoryError, demonstrating through Spring Boot controllers and multithreaded examples how main and child threads, daemon settings, and explicit OOM handling affect JVM shutdown behavior.

Lobster Programming
Lobster Programming
Lobster Programming
Will a JVM Exit When a Thread Runs Out of Memory? Deep Dive with Code

When a thread experiences an OutOfMemoryError (OOM), does the JVM exit? The following examples analyze this question.

OOM endpoint example

@RestController
@RequestMapping("/test")
public class OOMController {
    @GetMapping("/oom")
    public void oom() {
        List<byte[]> myList = new ArrayList<>();
        while (true) {
            myList.add(new byte[1024 * 1024 * 1024]);
        }
    }

    @GetMapping("/getString")
    public String getString() {
        return "success";
    }
}

Calling /test/oom continuously adds data to myList until the heap is exhausted, as shown in the first screenshot.

OOM memory exhaustion screenshot
OOM memory exhaustion screenshot

Even after the OOM, the /test/getString endpoint still returns “success” because it requires almost no heap memory.

Endpoint response after OOM
Endpoint response after OOM

The JVM shutdown behavior depends on where the OOM occurs:

(1) Uncaught OOM in the main thread

If an OOM is thrown in the main thread and not caught, the JVM typically terminates the program. In a Tomcat environment, each request runs in its own thread; an OOM in a request thread does not affect the main Spring Boot process unless the error propagates to the main thread.

(2) OOM in a child thread

When a child thread throws OOM, the JVM creates a destroyJavaVm thread that waits for all non‑daemon user threads to finish before shutting down. If a non‑daemon thread remains alive, the JVM stays alive.

Thread shutdown diagram
Thread shutdown diagram

Example with two threads (t1 continuously allocates memory, t2 prints messages):

public class MainTest {
    public static void main(String[] args) {
        new Thread(() -> {
            List<byte[]> list = new ArrayList<>();
            while (true) {
                System.out.println(Thread.currentThread().getName() + " 我就要发生oom了");
                byte[] bytes = new byte[1024 * 1024 * 1024];
                list.add(bytes);
                try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }
            }
        }, "t1").start();

        new Thread(() -> {
            while (true) {
                System.out.println(Thread.currentThread().getName() + "我来执行代码了");
                try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); }
            }
        }, "t2").start();

        System.out.println("主线程执行完毕了");
    }
}

The execution result shows that even after t1 encounters OOM, the JVM does not exit and t2 continues running.

Result with non‑daemon thread
Result with non‑daemon thread

If t2 is set as a daemon thread, the JVM exits automatically after t1’s OOM.

public class MainTest {
    public static void main(String[] args) {
        new Thread(() -> { /* same t1 code */ }, "t1").start();

        Thread t2 = new Thread(() -> {
            while (true) {
                System.out.println(Thread.currentThread().getName() + "我来执行代码了");
                try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); }
            }
        }, "t2");
        t2.setDaemon(true);
        t2.start();

        System.out.println("主线程执行完毕了");
    }
}

The final screenshot confirms that the JVM shuts down after the OOM when the only remaining thread is a daemon.

Result with daemon thread
Result with daemon thread

(3) Catching and handling OOM

If the OOM error is caught and properly handled—e.g., releasing resources or notifying the user—the JVM can continue executing other code.

(4) OS‑level termination

On Linux, if a process repeatedly throws OOM errors, the operating system may forcibly terminate the process for safety.

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.

javaJVMThreadSpring BootdaemonOutOfMemoryError
Lobster Programming
Written by

Lobster Programming

Sharing insights on technical analysis and exchange, making life better through technology.

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.