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退出时打印线程栈日志,方便排查是哪个线程调用了退出,以及退出码
守护线程可以在JVM退出时自动终止,避免了JVM无法退出的问题。 2. 释放资源:在执行Java请求时,需要确保释放所有占用的系统资源,如文件、网络连接等。 3. 检查JVM内存泄露:需要检查应用程序中的内存泄露,确保JVM...
运行阶段,JVM可以有多种线程类型,如用户线程和守护线程,其中用户线程的结束会导致JVM退出。JVM有两种运行模式,Server模式和Client模式,Server模式适用于长期运行的高性能应用,而Client模式启动更快,适合轻量...
这些数据区域在JVM启动时创建,在JVM退出时销毁。其中一些数据区域是线程独立的,即每个线程都有自己的数据区域;而另一些则是所有线程共享的。了解这些数据区域对于理解Java程序的运行机制以及优化Java应用至关重要...
8. **类的卸载**:Java中类一旦被加载就很难被卸载,因为垃圾回收器不会回收Class对象,除非JVM退出或者Class定义的ClassLoader被卸载。 深入理解ClassLoader的工作原理,对于优化JVM性能,解决类冲突问题,以及...
因此,守护线程不应持有任何共享资源,以免在没有释放的情况下导致JVM退出。 总结来说,Java中的守护线程是那些支持应用程序运行但不阻碍JVM退出的线程。正确使用守护线程可以优化资源管理,提高系统效率,并确保...
在 JVM 退出时,打印调用者-被调用者关系表以及调用次数编译java-callgraph 包是使用 maven 构建的。安装 maven 并执行以下操作mvn install这将生成一个target包含以下三个 jar 的目录javacg-0.1-SNAPSHOT.jar这是带...
但这个过程并不常见,因为一般只有在JVM退出或系统内存极度紧张时才会发生。 类的加载时机并非固定不变,而是根据特定条件触发。比如,创建类的实例、反射调用、启动主类、使用静态字段或方法等。虚拟机规范定义了...
然而,由于JVM通常不会主动卸载类,除非JVM退出或方法区需要释放空间,因此类的卸载在实际应用中较为罕见。 在Java中,类的加载时机由JVM实现决定,可能是静态初始化时、首次创建类实例时、访问类的静态成员或方法...
14. **JVM关闭**:当JVM退出时,可能有一些线程还在运行,因此需要注册`ShutdownHook`,这是一组在JVM关闭时执行的钩子函数,用于执行必要的清理工作。 15. **关闭钩子(Shutdown Hook)**:通过`Runtime....
- 卸载:JVM退出,或者ClassLoader被卸载,对应的类才会被卸载。 6. **ClassLoader与安全性** - 由于类加载过程中的双亲委派模型,恶意代码难以替换核心类,增加了系统的安全性。 - 安全管理器(SecurityManager...
9. **退出处理**:在JVM退出时,需要清理和关闭所有的JVMTI资源,以确保程序正常结束。 10. **错误处理**:JVMTI操作可能遇到各种错误,如内存不足、非法参数等。适当的错误处理是必要的,以确保工具的健壮性。 ...
hprof文件通常在程序退出时自动生成,包含HEAPDUMP、SITES、CPUSAMPLES和MONITORDUMP等记录。在程序运行过程中,也可以通过按下Ctrl-\(Solaris系统)或Ctrl-Break(Win32系统)来手动触发这些快照的生成。 #### ...
- 终止(Terminate):JVM退出。 5. **Tomcat的扩展性**: - Tomcat允许通过实现特定接口或继承特定类来自定义其行为,如`LifecycleListener`可以监听生命周期事件,`ContainerListener`可以监听容器事件。 - ...
2. 守护线程与用户线程:守护线程不阻碍JVM退出,而用户线程则会阻止JVM退出。 八、中断与异常处理 1. Thread.interrupt():用于中断线程,但不一定立即停止,需要在run()方法内部检查中断标志并作出相应处理。 2. ...
- **守护线程(Daemon Thread)**:不阻碍JVM退出,主要用于后台服务,如垃圾回收线程。在所有用户线程结束时,守护线程也会随之结束。 - **用户线程(User Thread)**:是应用程序的主要执行者,只要还有用户线程...
- **多线程和同步指令**:如`monitorenter`和`monitorexit`用于监视器锁的进入和退出,支持Java的synchronized关键字。 3. **字节码格式** 每条JVM指令由一个单字节的操作码(opcode)和可能的操作数组成。操作码...
1. Thread.setDaemon(true):将线程设置为守护线程,守护线程不会阻止JVM退出,只有当所有非守护线程结束时,JVM才会退出。 综上所述,Java多线程实例涵盖了创建线程、线程同步、线程池、线程通信等多个方面,学习...
守护线程不阻止JVM退出,而用户线程(如main线程)则会。通过Thread.setDaemon(true)可以将线程设置为守护线程。 锁是并发控制的关键,Java提供了两种类型的锁:隐式锁和显示锁。隐式锁主要通过`synchronized`...