Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/179.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C中exit(0)和Java中System.exit(0)的实践_Java_Android_C_Garbage Collection_Exit - Fatal编程技术网

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

C中exit(0)和Java中System.exit(0)的实践,java,android,c,garbage-collection,exit,Java,Android,C,Garbage Collection,Exit,在C中使用exit(0)不是一个好的做法,如果有其他选择的话,因为它不会释放资源。但是要在Java中使用System.exit(0),这里的情况如何?在这种情况下,可以信任垃圾收集器吗 C语言: exit(0); 爪哇: 但是要在java中使用System.exit(0),这里的情况如何?在这种情况下,可以信任垃圾收集器吗 在Java中调用System.exit时,垃圾收集器通常不会运行1。然而,在我听说过的任何JVM中,都有其他东西可以回收分配的所有对象。(通常在操作系统级别进行处理。)

在C中使用
exit(0)
不是一个好的做法,如果有其他选择的话,因为它不会释放资源。但是要在Java中使用
System.exit(0)
,这里的情况如何?在这种情况下,可以信任垃圾收集器吗

C语言:

 exit(0);
爪哇:

但是要在java中使用System.exit(0),这里的情况如何?在这种情况下,可以信任垃圾收集器吗

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

只有在JVM终止之前依赖对象终结器来完成一些重要的事情时,GC才不会运行这一事实才有意义

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

  • 一般来说,操作系统会处理这些事情。至少对于现代版本的Linux和UNIX,AFAIK是这样

  • 垃圾收集器无论如何都不知道这些资源。如果操作系统不能回收它们,那么Java垃圾回收器也帮不上忙

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


    1-如果您以前调用过
    runFinalizersOnExit(true)
    ,将在JVM退出时执行垃圾收集。但是,这是一种已弃用的方法。Oracle网站对此的解释如下:

    问:为什么Runtime.runFinalizersOnExit被弃用

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

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


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

    这样想。在C语言中,您将源代码构建到一个二进制文件中,该文件将根据逻辑编程规则和操作系统设置的规则自行执行。但是,操作系统不会为您管理内存。它处理事件并向硬件发送信息,告诉它如何运行,不多不少。在java中,所有代码都被编译成java自己的字节码。在执行时,它实际上在任何时候都不会与操作系统通信。设计用于运行该字节码的虚拟机正是该语言的功能所在。当你调用System.exit(0)时,你告诉虚拟机你正在运行的应用程序即将停止,从那里机器处理它自己的内存,这恰好包括你没有通过垃圾收集器删除的任何内容,但只有当虚拟机也在退出时。希望这能有所帮助

    如果您要杀死应用程序,为什么还要关心垃圾收集?这无关紧要——您要杀死应用程序。这将释放所有内存。那么为什么要关心垃圾收集呢?@Sotirios Delimanolis-不!在JavaAndroid中,您可以杀死活动,而不必杀死app@user2991252当你在Android中杀死一个活动时,操作系统会处理内存管理。这不取决于程序员。在大多数操作系统中,无论哪种情况,您都不必担心。然而,除了内存之外,还有其他资源需要担心:共享内存段、互斥量/信号量、套接字等。这些并不总是由C中的出口(0)来处理,但我不能代表Java。一般来说,确实如此,但通常SystemV IPC对象会在进程终止后保留,除非您特别努力清理它们。以前,我在调试/修复内核时,在内核上运行的一个程序连续转储了好几次,我已经达到了Linux内核对共享内存部分的限制。消息队列和信号量也可能发生同样的情况。请参阅Linux上ipcs和ipcrm的手册页。“在Java中调用
    System.exit
    时,垃圾收集器未运行。”--在Android中这可能是错误的。From:“如果runFinalizersOnExit(boolean)以前使用true参数调用过,那么所有对象都将首先被正确地垃圾收集和最终确定。”(强调添加)@TedHopp-On Java SE(至少)不推荐使用该方法。不过,我已将该信息添加为脚注。
     System.exit(0)