内存泄漏 - 没有垃圾收集器

时间:2011-09-18 09:37:24

标签: garbage-collection operating-system heap

让我们想一下内存泄漏程序,其中没有释放堆内存块并且程序终止。如果这是(比如说)Java程序,那么内置的垃圾收集器会在程序退出之前自动释放该堆块。

但是即使在C ++中,如果程序退出,内核也不会自动解除分配与该进程相关的所有空间。同样在Java代码中,内核必须为进程的文本部分(代码)解除分配空间(即使堆栈和堆部分由垃圾收集器解除分配)。使用垃圾收集器功能的总体优势是什么 - 只是通过程序本身而不是内核解除分配堆所需的时间增加了? (如果有任何这样的节省)

编辑:我的主要疑问是查看响应 - 当内存使用量达到极限时,GC会自动调用吗?因为,如果仅在程序终止之前调用GC,则对于长程序它不会有用。

2 个答案:

答案 0 :(得分:1)

  1. 假设内核在您之后清理。并非所有操作系统都会自动处理动态分配的内存。 (但公平地说:大多数现代的,至少在桌面上都可以。)
  2. 即使是回收所有内存的操作系统,只有在进程终止时才会执行。大多数程序在总运行时间内分配的内存远远超过任何给定时间点所需的内存(运行时间足够长,对于许多数据运算应用程序,“long”可能只需几秒钟。)
  3. 正因为如此,许多 - 特别是长时间运行的 - 进程会在他们的一生中产生越来越多的垃圾(不再使用的内存,并且不会再次使用),而没有任何摆脱的希望它没有终止。为了保持较低的内存使用率,你不想杀死并重新启动整个过程,是吗?
  4. 因为未使用的内存几乎从不(有很多进程无限期运行,有些进程可以运行数小时)被处理掉,所以一段时间后会出现严重的内存不足。您的浏览器将您在此会话期间打开的所有图像,HTML文档,JS对象等保存在内存中,因为您不必每隔几分钟就重新启动它。你说是浏览器中的废话和严重问题?我的观点完全正确。
  5. 此外,大多数(也就是所有好的)GC 解除所有 - 当他们认为值得时,他们会不时地运行但是当进程关闭时,内存中剩余的所有内容都会被释放到较低级别(无论是自定义分配器还是操作系统)。这也是为什么终结器不能保证运行的原因 - 在一个没有多次分配的短期运行程序中,GC可能永远不会运行。
  6. 所以不,GC不是为了节省时间。这是为了节省大量内存,防止长时间运行的分配密集型程序占用所有可用内存,并最终使每个人死于内存不足错误。

答案 1 :(得分:0)

假设程序分配了一些资源,它一直在运行时使用它,但在退出之前不会正确释放它。当这个程序退出时,内核会释放所有程序资源 - 没关系。

现在考虑一些函数在每次调用时创建内存泄漏的情况,并且此函数在一秒钟内被调用100次。几分钟或几小时后,此程序崩溃,因为没有空闲内存。

糟糕的是,使类型1的内存和资源泄漏的程序员通常会造成类型2的泄漏,从而产生脏的和不稳定的代码。专业程序员用0资源和内存泄漏编写完美的代码。如果垃圾收集器可用 - 没关系。如果不是 - 自己管理资源。

顺便说一下,仍有可能使用垃圾收集器进行泄密 - 就像众所周知的.NET事件源 - 消费者泄漏一样。因此,垃圾收集器非常有用,节省了大量的开发人员时间,但无论如何开发人员必须仔细管理程序资源。