`
lizhensan
  • 浏览: 377147 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

JVM的退出

    博客分类:
  • java
 
阅读更多
public static void main(String[] args) {
		ThreadTest t = new ThreadTest();
		t.test2();
	}

	// jvm什么时候推出
	@Test
	public void test2() {
		// 除直接kill,其它JVM终止都会调用该钩子
		Runtime.getRuntime().addShutdownHook(new Thread() {
			@Override
			public void run() {
				System.out.println("关闭JVM");
			}
		});
		Thread t = new Thread() {
			@Override
			public void run() {
				System.out.println("用户线程正在运行....");
				try {
					Thread.sleep(10 * 1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println("用户线程结束....");
			}
		};
		t.setDaemon(false);
		//如果是false,JVM会等到最用一个用户线程跑完才执行终止操作,JVM自动调用Shutdown,用户也可以自行调用System.exit(0)
		//如果是true,说明是守护线程,JVM任务是辅助用的,可有可无,JVM不会等待该线程
		t.start();
		System.out.println("程序执行完毕");
	}

 在eclipse中运行,如果是通过Junit的方式测试运行test2方法,是模拟不出来预想的情况的。直接就退出了,为什么呢?看下Eclipse调用Junit的入口代码就知道了

org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(String[])

try {
			RemoteTestRunner testRunServer= new RemoteTestRunner();
			testRunServer.init(args);
			testRunServer.run();
		} catch (Throwable e) {
			e.printStackTrace(); // don't allow System.exit(0) to swallow exceptions
		} finally {
			// fix for 14434
			System.exit(0);
		}

 

这里显示的调用了退出方法。所以JVM就直接退出并释放资源。

在自己的main函数中由于自己没有主动调用System.exit(0);

把处理权交给了JVM,JVM在退出前会等待所有的用户线程都关闭掉。

 

 public static void main(String[] args) {

ThreadTest t = new ThreadTest();

t.test2();

throw new RuntimeException("xxx");

}

及时main线程抛出异常,JVM一样会等待...

 

java.c  这块处理的源码

/*
 * Always detach the main thread so that it appears to have ended when
 * the application's main method exits.  This will invoke the
 * uncaught exception handler machinery if main threw an
 * exception.  An uncaught exception handler cannot change the
 * launcher's return code except by calling System.exit.
 *
 * Wait for all non-daemon threads to end, then destroy the VM.
 * This will actually create a trivial new Java waiter thread
 * named "DestroyJavaVM", but this will be seen as a different
 * thread from the one that executed main, even though they are
 * the same C thread.  This allows mainThread.join() and
 * mainThread.isAlive() to work as expected.
 */
#define LEAVE() \
    if ((*vm)->DetachCurrentThread(vm) != 0) { \
        JLI_ReportErrorMessage(JVM_ERROR2); \
        ret = 1; \
    } \
    (*vm)->DestroyJavaVM(vm); \
    return ret \

 

分享到:
评论

相关推荐

    javassist+javaAgent探针, 实现jvm退出时打印线程栈日志

    javassist+javaAgent探针, 实现jvm退出时打印线程栈日志,方便排查是哪个线程调用了退出,以及退出码

    执行java请求时导致在脚本执行结束时JVM无法退出

    守护线程可以在JVM退出时自动终止,避免了JVM无法退出的问题。 2. 释放资源:在执行Java请求时,需要确保释放所有占用的系统资源,如文件、网络连接等。 3. 检查JVM内存泄露:需要检查应用程序中的内存泄露,确保JVM...

    详细讲解了jvm在java中应用

    运行阶段,JVM可以有多种线程类型,如用户线程和守护线程,其中用户线程的结束会导致JVM退出。JVM有两种运行模式,Server模式和Client模式,Server模式适用于长期运行的高性能应用,而Client模式启动更快,适合轻量...

    JVM运行时数据区

    这些数据区域在JVM启动时创建,在JVM退出时销毁。其中一些数据区域是线程独立的,即每个线程都有自己的数据区域;而另一些则是所有线程共享的。了解这些数据区域对于理解Java程序的运行机制以及优化Java应用至关重要...

    探索JVM底层奥秘ClassLoader源码分析与案例讲解

    8. **类的卸载**:Java中类一旦被加载就很难被卸载,因为垃圾回收器不会回收Class对象,除非JVM退出或者Class定义的ClassLoader被卸载。 深入理解ClassLoader的工作原理,对于优化JVM性能,解决类冲突问题,以及...

    java 变形金刚中的守护神(守护线程)

    因此,守护线程不应持有任何共享资源,以免在没有释放的情况下导致JVM退出。 总结来说,Java中的守护线程是那些支持应用程序运行但不阻碍JVM退出的线程。正确使用守护线程可以优化资源管理,提高系统效率,并确保...

    深入理解ClassLoader工作机制.docx

    但这个过程并不常见,因为一般只有在JVM退出或系统内存极度紧张时才会发生。 类的加载时机并非固定不变,而是根据特定条件触发。比如,创建类的实例、反射调用、启动主类、使用静态字段或方法等。虚拟机规范定义了...

    详解java类的生命周期.doc

    然而,由于JVM通常不会主动卸载类,除非JVM退出或方法区需要释放空间,因此类的卸载在实际应用中较为罕见。 在Java中,类的加载时机由JVM实现决定,可能是静态初始化时、首次创建类实例时、访问类的静态成员或方法...

    JAVA并发编程实践-线程的关闭与取消-学习笔记

    14. **JVM关闭**:当JVM退出时,可能有一些线程还在运行,因此需要注册`ShutdownHook`,这是一组在JVM关闭时执行的钩子函数,用于执行必要的清理工作。 15. **关闭钩子(Shutdown Hook)**:通过`Runtime....

    了解Java ClassLoader

    - 卸载:JVM退出,或者ClassLoader被卸载,对应的类才会被卸载。 6. **ClassLoader与安全性** - 由于类加载过程中的双亲委派模型,恶意代码难以替换核心类,增加了系统的安全性。 - 安全管理器(SecurityManager...

    获取一个Java类的所有对象实例,基于JVMTI实现.zip

    9. **退出处理**:在JVM退出时,需要清理和关闭所有的JVMTI资源,以确保程序正常结束。 10. **错误处理**:JVMTI操作可能遇到各种错误,如内存不足、非法参数等。适当的错误处理是必要的,以确保工具的健壮性。 ...

    jvm

    hprof文件通常在程序退出时自动生成,包含HEAPDUMP、SITES、CPUSAMPLES和MONITORDUMP等记录。在程序运行过程中,也可以通过按下Ctrl-\(Solaris系统)或Ctrl-Break(Win32系统)来手动触发这些快照的生成。 #### ...

    WEB服务器工作机制由浅至深(9):【How Tomcat Works】第16章关闭钩子以及之后的章节简述

    - 终止(Terminate):JVM退出。 5. **Tomcat的扩展性**: - Tomcat允许通过实现特定接口或继承特定类来自定义其行为,如`LifecycleListener`可以监听生命周期事件,`ContainerListener`可以监听容器事件。 - ...

    Java多线程编程核心技术_完整版_java_

    2. 守护线程与用户线程:守护线程不阻碍JVM退出,而用户线程则会阻止JVM退出。 八、中断与异常处理 1. Thread.interrupt():用于中断线程,但不一定立即停止,需要在run()方法内部检查中断标志并作出相应处理。 2. ...

    sjava面试死锁

    - **守护线程(Daemon Thread)**:不阻碍JVM退出,主要用于后台服务,如垃圾回收线程。在所有用户线程结束时,守护线程也会随之结束。 - **用户线程(User Thread)**:是应用程序的主要执行者,只要还有用户线程...

    JVM指令集.zip

    - **多线程和同步指令**:如`monitorenter`和`monitorexit`用于监视器锁的进入和退出,支持Java的synchronized关键字。 3. **字节码格式** 每条JVM指令由一个单字节的操作码(opcode)和可能的操作数组成。操作码...

    java多线程实例

    1. Thread.setDaemon(true):将线程设置为守护线程,守护线程不会阻止JVM退出,只有当所有非守护线程结束时,JVM才会退出。 综上所述,Java多线程实例涵盖了创建线程、线程同步、线程池、线程通信等多个方面,学习...

    并发编程从入门到放弃系列开始和结束.doc

    守护线程不阻止JVM退出,而用户线程(如main线程)则会。通过Thread.setDaemon(true)可以将线程设置为守护线程。 锁是并发控制的关键,Java提供了两种类型的锁:隐式锁和显示锁。隐式锁主要通过`synchronized`...

    jstack生成的Thread Dump日志1

    2. **守护线程/非守护线程**:守护线程(daemon)在后台执行任务,不阻止JVM退出;非守护线程则是程序的核心,所有非守护线程结束时,JVM才会终止。 3. **线程优先级**:默认优先级为5,数值越大,优先级越高,但并...

Global site tag (gtag.js) - Google Analytics