【问题标题】:Practice of exit(0) in C and System.exit(0) in JavaC中exit(0)和Java中System.exit(0)的实践
【发布时间】:2013-11-24 22:23:10
【问题描述】:

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

C语言:

 exit(0);

Java:

 System.exit(0)

【问题讨论】:

  • 如果您要杀死应用程序,为什么还要关心垃圾收集?
  • 这无关紧要 - 您即将终止应用程序。这将释放所有内存。那么为什么要关心垃圾回收呢?
  • @Sotirios Delimanolis - 不!在 Java android 中,你 KILL Activity,而不是应用程序
  • @user2991252 当您在 Android 中终止活动时,操作系统会处理内存管理。这不取决于程序员。
  • 在大多数操作系统中,您不必担心任何一种情况。但是,除了内存之外,还有其他资源需要担心:共享内存段、互斥体/信号量、套接字等。这些并不总是由 C 中的 exit(0) 处理,但我不能代表 Java。

标签: java android c garbage-collection exit


【解决方案1】:

但是要在 java 中使用 System.exit(0) - 它在这里怎么样?在这种情况下可以信任垃圾收集器吗?

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

只有在 JVM 终止之前依赖对象终结器来处理如此重要的事情时,GC 不运行的事实才有意义。

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

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

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

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


1 - 如果您之前调用过runFinalizersOnExit(true),则会在 JVM 退出时执行垃圾回收。但是,这是一种已弃用的方法。 Oracle 网站是这样解释的:

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

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

此外,调用不是“线程安全的”,因为它设置了一个 VM 全局标志。这迫使每个类都有一个终结器来防御活动对象的终结!

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

【讨论】:

  • 一般来说,确实如此,是的,但通常 System V IPC 对象会在进程终止后保留,除非您特别努力清理它们。在我正在处理内核的程序在调试/修复它时连续多次转储之前,我已经达到了共享内存部分的 Linux 内核限制。消息队列和信号量也会发生同样的情况。请参阅 Linux 上 ipcs 和 ipcrm 的手册页。
  • “当你在 Java 中调用 System.exit 时,垃圾收集器没有运行。” -- 这在 Android 中可能是错误的。来自the docs“如果之前使用 true 参数调用了 runFinalizersOnExit(boolean),则所有对象都将被正确地进行垃圾收集并首先完成。”(强调添加)
  • @TedHopp - 在 Java SE 上(至少)该方法已被弃用。但是,我已将该信息添加为脚注。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-18
    • 1970-01-01
    • 2013-08-19
    • 1970-01-01
    相关资源
    最近更新 更多