如果程序已经退出,为什么要释放资源?
许多库(例如 SDL 等)在其教程中都调用了在退出程序之前释放资源的方法,但据我所知,大多数操作系统在退出时会从进程中释放所有内存,为什么我需要费心去释放如果应用程序无论如何都会退出的话?
Many libraries like SDL, etc, etc have in their tutorials method calls that free resources right before quitting the program, but as far as I know, most OSes free all memory from the processes when they quit, why do I need to bother to free them if the application is going to quit anyway?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(18)
内存和资源不是一回事。
内存会自动释放。
资源可能会也可能不会自动释放。
Memory and resources are not the same thing.
Memory is released automatically.
Resources may, or may not, be released automatically.
即使您的操作系统(并非所有操作系统都这样做)在退出时释放内存,也有一些原因:
Even if your OS (not all do that) frees memory at exit, there are some reasons:
分配给程序的资源是否会被回收取决于操作系统。请注意,某些嵌入式系统不会释放资源。
大多数操作系统都会回收并释放分配的资源,但依赖操作系统的行为来实现这一点是不好的做法,因此您应该在退出程序之前释放所有获取的资源。
Whether the resources allocated to a program will be reclaimed or not depends on the Operating systems. Note that specifically some embedded systems do not free the resources.
Most operating systems do reclaim and free the resources allotted but it is bad practice to rely on the behavior of the OS for this and hence you should free all the acquired resources before you quit your program.
总的来说,我同意其他人所说的:如果你不在小事上养成良好的习惯,那么你在大事上也会失败。然而,你的问题(一个古老的)响了,关于仅崩溃软件。
虽然这个概念比您原来的问题延伸了“一点”(它不仅涉及操作系统资源,还涉及您自己的资源(打开文件等),您可能仍然对它感兴趣。
基本思想是,如果软件应该面对崩溃时不破坏用户数据等(想想数据库/tx日志等)为什么你应该设计/编程一个干净的退出路径如果你需要重新启动,重新运行它,你不妨“让它崩溃”。
好吧,我想人们可以争论一下整天都这样,但仍然很有趣。
In general I agree what others have said: if you don't practice good habits in the little things, you'll fail with the big ones as well. However your question rang (an old) bell, about crash-only software.
While that concept extends "a little" further than your original question (it not only deals with OS resources, but with your own (open files, etc.), you might still be interested in it.
The basic idea is, if software should not destroy user data, etc. in the face of a crash (think of databases / tx logs, etc.) why should you even design/program a clean exit path. If you need to restart, rerun it, you might as well "let it crash".
Well, I guess one can argue about the virtues of that all day, but it is interesting nevertheless.
收拾好自己是个好主意。
其一 - 释放资源将以受控方式整理文件描述符/网络连接/共享内存等。
其次,如果您使用诸如
purity
之类的东西,您可以确保所有内存都被考虑在内 - 从而更好地感觉到没有发生内存泄漏。It is a good idea to tidy up after yourself.
For one - freeing up resources will tidy up file descriptors/network connections/shared memory etc. in a controlled manner.
Secondly, if you are using something like
purity
you can ensure that all the memory is taken into account of - thus giving a better sense that no memory leaks are occurring.我想首先应该提到的是,并非所有资源都是相同的。
这些结构(在大多数操作系统中)都不会在应用程序关闭时自动清理:
......我确信我忘记了一些。
总的来说,可能很容易知道您的应用程序是否使用任何这些类型的对象及其控件。然而,在较大的应用程序中,不难达到这样的程度:您拥有一些深度嵌入的(第 3 方?)子系统,该子系统确实分配了一个或多个这些特殊结构,并且如果应用程序的其余部分像筛子一样泄漏,你可能有麻烦了。
这实际上是一个工程学科的问题,它表明您的应用程序应该在退出时自行清理。您现在可能不需要它,但随着您的应用程序变得越来越大,您可能会欣赏它。
I suppose the first thing that should be mentioned is that not all resources are the same.
None of these structures (in most OSes) are automatically cleaned up at application close:
... and I'm sure I'm forgetting some.
In the small, it might be easy to know whether your application uses any of these types of objects and control for it. However, in larger applications it isn't hard to get to a point where you have some deeply-embedded (3rd party?) subsystem that does allocate one or more of these special structures and if the rest of your application leaks like a sieve, you might be in trouble.
It is really a matter of engineering discipline that says your application should clean up after itself on exit. You may not need it now but you might appreciate it later as your application gets larger.
我看到的原因之一是:
假设您在应用程序退出时将内存泄漏转储到开发环境的输出窗口中。如果您没有以正确的方式“清理”,您将无法从“不理会它”的所有泄漏中检测到真正的泄漏
One reason I see is:
Assume that you have the memory leaks dumped in the output window of your development environment on application exit. If you do not "clean-up" in a proper way you will have problems detecting the true leaks from all the leaks that come from "not bothering with it"
确实,今天几乎所有主流操作系统确实都会释放程序在终止时分配的所有(或大部分)资源。然而,首先并非所有资源都如此(例如,在我的 mac 上,当程序终止时未正确关闭时,打开套接字会保持打开状态一段时间),其次我相信并非所有操作系统都如此。
从历史上看,操作系统根本不会打扰(特别是一些较旧的 16 位操作系统),因此在编程终止时清理所有资源已经成为并且仍然是良好的编程实践,不清理自己的东西的程序员通常被认为是糟糕的程序员。
Well it is mostly true that today almost all mainstream operating systems do indeed free all (or most) resources a program has allocated upon its termination. However, this is firstly not true for all resources (e.g. on my mac open sockets stay open for a while when not closed properly at program termination) and secondly I believe not for all operating systems.
Historically, OSses did not bother at all (esp. some of the older 16bit OSses) so cleaning up all your resources upon programming termination has become and still is good programming practice and a programmer not cleaning up his stuff is generally considered a bad programmer.
首先:当进程结束时,操作系统并不释放所有资源,例如:
因此,一旦您以相同的方式管理所有资源,您就在做正确的事情。
First of all: not all resources are freed by the OS when process ends, for example:
So once you manage all resources in same way you are doing the right thing.
你是对的,大多数现代操作系统都会在应用程序退出时为你释放内存、文件句柄等。因此,如果应用程序可用的资源是无限的,我完全同意您的观点,并且不会费心释放任何资源。
事实上,资源并不是无限的,实际上恰恰相反,因此您获取的任何东西都是系统上运行的其他应用程序无法拥有的。在许多情况下,您不需要在应用程序的整个生命周期中使用资源,而只是应用程序的一部分,因此您希望与系统的其余部分很好地配合,并且只在需要时获取您需要的资源。
不释放资源的做法在嵌入式设备中很常见,因为对于这些设备来说,应用程序是唯一运行的东西,它甚至无法退出,唯一的出路就是关闭设备。我使用一个这样的系统,虽然嵌入式设备不会因为不发布东西而出现问题,但我们工程师却因为以下几个原因而受到困扰:
我的建议是,你编写代码时就好像操作系统不会帮助你一样,因为这会给你将来改进软件的最多选择。
You are correct, most modern operating systems will release memory, file handles, etc. for you when the application exits. So I would fully agree with you and not bother releasing any resources if resources available to applications were unlimited.
The fact is, resources are not unlimited, it's actually quite the opposite, so anything you take is something another application running on the system cannot have. In many cases you will need a resource not throughout the life of your app, but only for some portion of it, so you want to play nice with the rest of the system and only take what you need while you need it.
The practice of not releasing resources is very common in embedded devices, since for these the application is the only thing running, and it doesn't even get to exit, the only way out is to turn off the device. I work with one such systems, and while the embedded device has no issues from not releasing stuff, we engineers suffer from it for several reasons:
My advice is that you write the code as if the OS won't help you, as that is what will give you the most choices to improve the software in the future.
这些都是良好的礼仪。
而且你永远不知道你是否想把你的程序变成将来持续不断地运行的东西。
也就是说,这不是强制性的,并且一如既往,如果您知道自己在做什么,您就可以违反规则。
These are good manners.
And you never know if you want to turn your program into something persistently running over and over again in the future.
That said, it is not mandatory and as always you can break the rules if you know what you're doing.
操作系统在进程关闭后尝试释放进程仍保留的所有资源,作为保持系统运行的最后努力。应用程序应该自行清理,但操作系统的自动清理旨在阻止编写错误的程序因内存泄漏、保留文件等而导致整个系统瘫痪。所以你真的不应该依赖它作为您的应用程序关闭的默认模式!理想情况下,操作系统永远不需要在进程关闭后进行清理,因为所有程序都应该编写良好,以便在自行清理后进行清理。然而,在实践中,有些软件有错误或者只是编写得不好,操作系统在这些懒惰的程序之后进行清理是一个有用的功能。
此外,操作系统无论如何也不会清理某些资源。如果您将一个文件写入磁盘并打算在关机时删除它,操作系统将不会自动删除该文件(如果它是用户的文档怎么办?)。但如果您自己不清理它,您的程序就会永久“泄漏”磁盘空间。对于除文件之外的其他类型的资源,还有许多其他示例。
因此,不要编写假设操作系统会清理的糟糕软件:它可能不会 100% 完成清理工作,而且该机制仅适用于蹩脚软件。而是编写好的软件!
The operating system tries to free all resources still held by a process after it closes as a last ditch effort to keep the system running. Applications are supposed to clean up after themselves, but the OS's auto-cleanup is designed to stop badly written programs taking down the whole system by memory leaks, held files etc. So you really should not rely on it as the default mode for your application to be shut down! Ideally, the OS will never have to clean up after a process has shut down, because all programs should be well-written to clean up after themselves. However, in practice, some software has mistakes or is simply poorly written and it is a useful feature for the OS to clean up after these lazy programs.
Also, the OS will not clean up some resources anyway. If you write a file to disk and intend to remove it on shut-down, the OS will not delete that file automatically (what if it was the user's document?). But if you don't clean it up yourself, your program has permanently "leaked" disk space. There are many other examples for other types of resources other than files.
So don't write bad software which assumes the OS will clean up: it probably won't do it 100%, and that mechanism is only for crappy software. Write good software instead!
一旦您尝试使用 Valgrind 或其他工具查找内存泄漏,即使对于其生命周期与应用程序的生命周期相对应的对象,释放内存的意义也立即显而易见,因为您的输出将充斥着有关这些对象的报告。毕竟,泄漏仍然是泄漏。
The sense of releasing the memory even for objects whose lifetime corresponds to that of an application is immediately obvious once you try to find a memory leak with Valgrind or something, because your output wil be flooded with reports on those objects. After all, a leak is still a leak.
应用程序退出时不需要释放内存。操作系统负责回收内存。正如其他人提到的,像打印机、文件这样的资源需要释放它们的锁,以允许其他程序访问它们。
假设您的代码没有释放任何内存(即使在运行时),并且当您的代码/项目大小增加时,它将耗尽您的所有系统内存,并且维护变得很难修复它们。因此,对于未来的所有目的,释放内存是一个很好的做法。
It is not required to free memory when the application quits. The OS takes care of reclaiming the memory. As others mentioned, resources like printer, files require to free their locks for allowing other programs to access them.
Say if your code does not free any memory (even when it runs) and when your code/project size increases, it will eat all of your system memory and maintenance becomes hard to fix them. So for all future purposes, it is a good practice to free memory.
如您所知,根据操作系统的不同,内存通常(希望如此!)在进程退出时自动释放。
然而,许多库(例如 SDL)要求操作系统及时分配系统资源,不会及时释放(甚至可能直到关闭)除非明确由应用程序释放。
除了对操作系统友好并进行清理之外,释放您分配的任何内存对于运行时间未知的任何应用程序都很重要,因为该内存占用了其他应用程序可能需要的空间。
自己清理也是一个好习惯。 :)
As you know, depending on the OS, memory is usually (hopefully it is!) release automagically when the process exits.
However, many libraries, like SDL, ask the OS to allocate system resources that do not get freed in a timely fasion (maybe not even untill shutdown) unless explicitly freed by the application.
Besides being nice to the operating system and cleaning up for it, freeing any memory you allocate is important in any application that runs for an unknown amount of time because that memory takes up space that other applications might need.
It's also a good habit to clean up after yourself. :)
正如其他答案指出的那样,资源和内存之间存在差异。我只能在 Win32 api 的上下文中谈论,但我确信类似的概念也适用于像 SDL 这样的库。有些库可能提供资源的自动释放,有些则不然。无论如何,释放资源始终是一个好习惯。设备特定资源是如果不释放可能会导致问题的资源示例。您可能需要查看库的文档以了解有关资源管理的详细信息。
As the other answers point out, there is a difference between resources and memory. I can speak only in context of the Win32 api, but I'm sure that similar concepts are applicable for libraries like SDL. Some libraries may provide for automatic release of resources, some may not. It is always good practice to free up your resources irregardless. Device specific resources are an example of resources that may cause problems if they are not freed. You might want to check with the documentation of your library for details about resource management.
我知道我迟到了,但是请释放你所有的内存和资源,如果没有其他原因,除了因为当你最终遇到真正的内存泄漏时,就像在循环内一样,那么我最不需要的就是你的垃圾像 valgrind 一样弄乱我的内存分析器输出。
其次,清理内存不是问题,使用智能指针可以为您完成所有工作,几乎没有任何开销。
最后,如果它是一个库,这是更不可原谅的,我不在乎它是否不是连续泄漏(即 1 次垃圾 - 例如:创建单例),库不应该在 freestore 上留下数据。
I know I am late to the party, but please free all your memory and resources, if for no other reason than because when you end up getting a real memory leak, like on inside a loop, then the last thing I need is your garbage cluttering up my memory profilers output like valgrind.
Secondly cleaning up memory isn't a problem use smart pointers the do all the work for you with little to no overhead.
Finally, this is even more inexcusable if it a library, I don't care if it is not a continuous leak (ie 1 off garbage - eg: creation of a singleton) a library should not leave data on the freestore.
每当任何新进程启动时,都会为其分配一些内存。内存可以有四种类型:
本地通常用于 main() 变量的地址,因为这些主变量将被频繁使用。 Global 保存全局变量的记录。堆内存被分配(分配页面)给程序或进程,它具有程序的数据和函数的信息。
操作系统使用指针的概念实际上发生了什么。每当程序中一个指针开始指向其他内存(由于某些代码错误)并停止指向前一个内存位置时,最后一个内存空间仍在堆内存中使用。但这个内存空间没有任何用处。当任何程序退出时,它都会根据其变量和函数位置释放内存。但正如我所说,未指向的内存仍然有数据,但没有人指向它,因此程序无法释放它。
为了释放未使用的内存位置,我们使用 free()。如malloc、realloc、calloc、free都是堆内存的功能。当我们调用 free 时,它会删除为程序分配的页面,并且还会释放未使用的内存。
分配给您的程序的 50-100 个内存位置。 a 和 b(程序中的变量)分别指向 60 和 70。由于某些代码错误,b 开始指向 60。所以现在 a 和 b 都指向 60。现在没有人指向 70。当程序开始退出时,它将获取a的内存位置并释放它。然后它将获取b的内存位置并释放它。但是程序永远不会知道70的位置,因为没有人指向它。所以它不会释放 70 的内存。
而当你调用 free() 时,它会直接释放整个页面,并且整个 50-100 内存位置将被释放。现在,非指向和指向的内存位置都可以免费使用。
现在,语言都有垃圾收集器来执行 free() 的功能。但如果我们谈论操作系统,那么它们必须自己完成,因此在库中总是使用免费的。这也是编写代码的最佳方式。
Whenever any new process starts some memory is allocated to it. The memory can be of four types as:
Local generally used for the main() variable's addresses because these main variables will be used frequently. Global keeps the record of global variables. Heap memory is allocated (pages are allocated) to programs or process and it have the information of program's data and functions.
What actually happens that OS uses the concept of pointers. And whenever in program one pointer start pointing to some other memory(due to some code error) and stop pointing to previous memory location then the last memory space is still in use in heap memory. but this memory space is of no use. When any program exits it releases the memory according to its variables and functions location. But as i told the un-pointed memory have still data but no one is pointing to it so program can not release it.
To release that unused memory location we use free(). As malloc, realloc, calloc, free all are the functions of heap memory. When we call free it delete the pages that were allocated for the program and it also releases that unused memory too.
50-100 memory location allocated to your program. a and b(variables in your program) are pointing to 60 and 70. due to some code error , b starts pointing to 60. So now a and b both pointing to 60. No one pointing to 70 now. When program will start exit it will get the memory location of a and release it .Then it will get the memory location of b and release it .But program will never come to know the location of 70 because no one is pointing it.So it wont release the memory of 70.
Whereas when u call free() it directly release the whole page and with that whole 50-100 memory location will be release. Now both un-pointed and pointed memory locations are free for use.
Now a days the languages have garbage collector to do the function of the free(). But if we talk about the OSes then they have to do it itself so in libraries always free is used. And it is also best way of writing code.