在C中使用exit(0)
不是一个好习惯,如果有替代方案,因为它不会释放资源,例如。但是在Java中使用System.exit(0)
- 这是怎么回事?在这种情况下,人们可以信任垃圾收集器吗?
C语言:
exit(0);
爪哇:
System.exit(0)
答案 0 :(得分:2)
但是在java中使用System.exit(0) - 这是怎么回事?在这种情况下,人们可以信任垃圾收集器吗?
在Java中调用System.exit
时,垃圾收集器通常不会运行 1 。但是,在我曾经听过的任何JVM中,还有一些东西可以回收所有已分配的对象。 (通常在操作系统级别处理。)
如果您在JVM终止之前依赖于对象终结器,那么GC不会运行这一事实非常重要。
假设,如果您的Java应用程序使用JNI(等)来调用本机方法,那么这些方法可以访问可能存在问题的系统资源。但是:
作为一般规则,操作系统 负责处理此类事情。至少它适用于现代版本的Linux和UNIX,AFAIK。
垃圾收集器无论如何都不了解这些资源。如果操作系统无法回收它们,那么Java垃圾收集器将无法提供帮助。
如果确实需要清理Java程序获取的这些资源(通过本机代码),那么最好的方法是在本机代码方法中实现清理,并使用" shutdown hook"运行它们。如果您拨打System.exit
。
1 - 如果您之前已调用runFinalizersOnExit(true)
,则将在JVM出口上执行垃圾收集。但是,这是已弃用的方法。 Oracle网站解释如下:
功能
问:为什么不推荐使用Runtime.runFinalizersOnExit?功能
答:因为它本质上是不安全的。它可能导致在活动对象上调用终结器,而其他线程同时操作这些对象,从而导致不稳定的行为或死锁。如果对象正在最终确定的类被编码为"防御"可以防止这个问题。这个电话,大多数程序员都不会反对它。他们假设一个对象在调用终结器时已经死了。
此外,呼叫不是"线程安全"从某种意义上说它设置了VM全局标志。这迫使每个类都有一个终结器来防御活动对象的最终化! 功能
简而言之,这是一种危险的方法,它不会直接处理OP担心的那种资源。
答案 1 :(得分:1)
这样想。在C中,您将源代码构建为二进制文件,该文件仅在符合逻辑编程规则和操作系统设置的规则的情况下自行执行。然而,操作系统不会为您管理您的记忆。它处理事件并向硬件发送信息,告诉它如何运行,仅此而已。在java中,所有代码都被编译成java自己的字节码。在执行时,它实际上并不在任何时候与OS通信。设计用于运行该字节码的虚拟机就是说话。当你调用System.exit(0)时,你告诉虚拟机你正在运行的应用程序正在停止,从那里机器处理IT'S OWN MEMORY,恰好包括你尚未通过垃圾收集器,但仅当VM正在退出时。希望有所帮助