繁体   English   中英

Java中C和System.exit(0)中exit(0)的实践

[英]Practice of exit(0) in C and System.exit(0) in Java

如果有替代方法,在C中使用exit(0)不是一个好习惯,因为它不会释放资源。 但是在Java中使用System.exit(0) - 它是如何在这里的? 在这种情况下,可以信任垃圾收集器吗?

C语言:

 exit(0);

Java的:

 System.exit(0)

但是在java中使用System.exit(0) - 这是怎么回事? 在这种情况下,人们可以信任垃圾收集器吗?

在Java中调用System.exit时,垃圾收集器通常不会运行1 但是,在我听说过的任何JVM中,还有一些东西可以回收所有已分配的对象。 (通常在操作系统级别处理。)

如果您在JVM终止之前依赖于对象终结器,那么GC不运行的事实才有意义。

假设,如果您的Java应用程序使用JNI(等)来调用本机方法,那么这些方法可以访问可能存在问题的系统资源。 然而:

  1. 作为一般规则,操作系统确实处理这些事情。 至少它适用于现代版本的Linux和UNIX,AFAIK。

  2. 垃圾收集器无论如何都不了解这些资源。 如果操作系统无法回收它们,那么Java垃圾收集器将无济于事。

如果确实需要清理Java程序获取的这些资源(通过本机代码),那么最好的方法是在本机代码方法中实现清理,并使用“shutdown hook”来运行它们。 如果调用System.exit将运行关闭挂钩。


1 - 如果您之前调用了runFinalizersOnExit(true)则将在JVM出口上执行垃圾收集。 但是,这是一种弃用的方法。 Oracle网站解释如下:

问:为什么不推荐使用Runtime.runFinalizersOnExit?

答:因为它本质上是不安全的。 它可能导致在活动对象上调用终结器,而其他线程同时操作这些对象,从而导致不稳定的行为或死锁。 虽然如果对象正在最终确定的类被编码为“防御”此调用,则可以防止此问题,但大多数程序员不会对其进行防御。 他们假设一个对象在调用终结器时已经死了。

此外,在设置VM全局标志的意义上,该调用不是“线程安全的”。 这迫使每个类都有一个终结器来防御活动对象的最终化!

简而言之,这是一种危险的方法,它不会直接处理OP担心的那种资源。

想想这样。 在C中,您将源代码构建为二进制文件,该文件仅在符合逻辑编程规则和操作系统设置的规则的情况下自行执行。 然而,操作系统不会为您管理您的记忆。 它处理事件并向硬件发送信息,告诉它如何运行,仅此而已。 在java中,所有代码都被编译成java自己的字节码。 在执行时,它实际上并不在任何时候与OS通信。 设计用于运行该字节码的虚拟机就是说话。 当你调用System.exit(0)时,你告诉虚拟机你正在运行的应用程序正在停止,从那里机器处理IT'S OWN MEMORY,恰好包括你尚未通过垃圾收集器,但仅当VM正在退出时。 希望有所帮助

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM