如果程序已经退出,为什么还需要免费资源?

27

许多库,例如SDL等,在其教程中调用方法来在退出程序之前释放资源,但据我所知,大多数操作系统在退出进程时会释放所有内存,那么如果应用程序将要退出,为什么我还需要费心去释放它们呢?

许多库的教程中包括在退出程序之前释放资源的方法调用,主要出于以下原因:虽然大多数操作系统在进程终止时会回收所有内存,但是对于某些特殊的资源(如打开的文件、网络连接等),这些资源必须在程序终止之前手动释放,否则可能会导致一些问题,比如数据损坏、泄漏等。因此,在编写程序时,建议始终按照库的教程进行资源释放操作,即使您认为某些资源不需要手动释放。


也许,只是为了保持一致?一个好习惯? - Nawaz
虽然这个问题有一定的价值,但我认为它不适合在SO上讨论,因为如果没有特定的使用情境,这只会导致一场宗教战争。 - John Dibling
18个回答

2
操作系统在进程关闭后会尝试释放该进程仍然持有的所有资源,以最后的努力来保持系统运行。应用程序应该自我清理,但操作系统的自动清理是为了防止由于内存泄漏、文件占用等问题而导致糟糕编写的程序拖垮整个系统。因此,您不应该依赖它作为应用程序默认关闭模式!理想情况下,操作系统永远不需要在进程关闭后进行清理,因为所有程序都应该编写得很好,可以自我清理。然而,在实践中,一些软件存在错误或者只是编写得很差,这时操作系统清理这些懒惰程序的功能就变得非常有用。
此外,操作系统也不会清理某些资源。如果您将文件写入磁盘并打算在关闭时删除它,则操作系统不会自动删除该文件(如果它是用户的文档怎么办?)。但是,如果您不自行清理它,则您的程序已经永久“泄漏”了磁盘空间。还有许多其他类型资源的例子。
因此,请勿编写假设操作系统会进行清理的糟糕软件:它可能无法100%地完成清理,并且该机制仅适用于糟糕的软件。请编写良好的软件!

2

这些是好的习惯。

你永远不知道将来是否需要将你的程序变成一个持续运行的东西。

话虽如此,这并非强制要求,如果你知道自己在做什么,总是可以打破规则。


1
释放那些生命周期与应用程序相对应的对象的内存是显而易见的,当您尝试使用Valgrind或其他工具查找内存泄漏时,这一点立刻显现出来,因为您的输出将被大量报告这些对象。毕竟,泄漏仍然是泄漏。

0

应用程序退出时无需释放内存,操作系统会负责回收内存。正如其他人所提到的,像打印机、文件等资源需要释放它们的锁定,以允许其他程序访问它们。

假设您的代码在运行时不释放任何内存(即使它运行),当您的代码/项目大小增加时,它将占用所有系统内存,并且维护变得难以修复。因此,为了所有未来目的,释放内存是一个好习惯。


0

众所周知,根据操作系统的不同,内存通常会(希望如此!)在进程退出时自动释放。

然而,许多库(如SDL)要求操作系统分配系统资源,这些资源不会及时释放(甚至可能直到关机)除非应用程序明确释放

除了对操作系统有好处并为其进行清理外,释放您分配的任何内存对于运行时间未知的任何应用程序都很重要,因为该内存占用其他应用程序可能需要的空间。

也养成一个好习惯,注意自己的清洁。 :)


0
正如其他答案所指出的那样,资源和内存之间存在差异。我只能在Win32 api的上下文中说话,但我相信类似的概念也适用于像SDL这样的库。一些库可能提供自动释放资源的功能,而有些则可能没有。无论如何,释放资源总是一个好习惯。设备特定的资源就是可能会导致问题的资源之一,如果它们没有被释放。您可能需要查阅您的库文档以了解有关资源管理的详细信息。

0

我知道我来晚了,但请释放所有内存和资源,即使没有其他原因,因为当您最终遇到真正的内存泄漏(例如在循环内部)时,我最不需要的就是您的垃圾杂乱无章地堆积在我的内存分析器输出中,如valgrind。

其次,清理内存不是问题,使用智能指针可以为您完成所有工作,几乎没有开销。

最后,如果这是一个库,那么这更加不可原谅,我不关心它是否是不连续的泄漏(例如创建单例的1次性垃圾),库不应该在自由存储器上留下数据。


-1

每当一个新进程启动时,都会为其分配一些内存。内存可以分为四种类型:

 1.Heap
 2.Local
 3.Virtual
 4.Global

局部变量一般用于main()变量的地址,因为这些主要变量将经常使用。全局变量保留全局变量的记录。堆内存分配给程序或进程(分配页面),并且具有程序数据和函数的信息。

实际发生的是,操作系统使用指针的概念。每当程序中的一个指针开始指向某个其他内存(由于某些代码错误)并停止指向先前的内存位置时,最后一个内存空间仍在堆内存中使用。但是,这个内存空间没有用处。当任何程序退出时,它会根据其变量和函数位置释放内存。但是,正如我所说的,未被指向的内存仍然具有数据,但没有人指向它,因此程序无法释放它。

为了释放未使用的内存位置,我们使用free()。因为malloc、realloc、calloc、free都是堆内存的函数。当我们调用free时,它删除为程序分配的页面,并释放未使用的内存。

  In simple words,

程序分配了50-100个内存位置。a和b(程序中的变量)指向60和70。由于某些代码错误,b开始指向60。所以现在a和b都指向60。现在没有人指向70。当程序退出时,它将获得a的内存位置并释放它。然后它将获得b的内存位置并释放它。但是程序永远不会知道70的位置,因为没有人指向它。因此,它不会释放70的内存。

而当您调用free()时,它直接释放整个页面,并释放整个50-100个内存位置。现在未指向和已指向的内存位置都可以自由使用。

现在的语言都有垃圾收集器来执行free()函数的功能。但是,如果我们谈论操作系统,则必须自己执行该功能,因此在库中始终使用free。这也是编写代码的最佳方式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接