2011-09-18 33 views
0

让我们想起一个内存泄漏程序,其中堆内存块未被释放并且程序终止。如果这是一个Java程序,内置的垃圾回收器会在程序退出之前自动释放这个堆块。内存泄漏 - 缺少垃圾回收器

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

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

+0

如果您的程序要运行很长时间会怎么样?在这种情况下,程序可以分配所有可用内存,当然也会失败。因此,即使操作系统在终止时释放内存,程序也必须对其分配的内存负责。 – Isaac

+0

这将取决于。在程序中可以随时调用Java中的GC吗?通过调用我的意思是它可以自动触发内存使用量达到极限时?因为如果只有在程序终止时才调用GC,对于长时间运行的程序来说,这无关紧要。 – Hari

回答

1
  1. 这假定内核在你之后清理完毕。并非所有操作系统都会自动处理动态分配的内存。 (但要公平:至少在桌面上,大多数现代应用都会这样做)
  2. 即使回收所有内存的操作系统也只能在进程终止时执行。大多数程序在总运行时间内分配的内存要比他们在任何给定时间点需要的时间多得多(当运行时间足够长时,对于许多数据处理应用程序,“long”可能只有几秒钟)。
  3. 因此,许多 - 尤其是长时间运行的进程会在他们的整个生命周期内创造出越来越多的垃圾(不再使用的内存,并且不会再被使用),而没有任何希望摆脱它没有终止。你不想为了保持内存使用率低而重新开始整个过程​​,是吗?
  4. 因为未使用的内存几乎从不(有很多进程无限期地运行并且有些可以运行几个小时)被处置,所以一段时间后会出现严重的内存短缺。您的浏览器会将您在此会话期间打开的所有图像,HTML文档,JS对象等存储在内存中,因为您不会每隔几分钟就重新启动一次。这是废话和浏览器中的严重问题,你说?我的确切点。
  5. 此外,大部分(也就是说,所有好的)选区解除分配一切 - 他们不时运行时,他们认为这是值得的,但是当进程关闭,剩下的一切在内存中被释放到较低的级别(不管是自定义分配器还是操作系统)。这也是终结者不能保证运行的原因 - 在一个短期运行的程序中,如果分配不足,GC可能永远不会运行。

所以不,GC不是节约时间。这是关于节省大量的内存,防止长时间运行的分配密集型程序占用所有可用内存,并最终导致每个人都因内存不足错误而死亡。

0

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

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

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

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