对于64位操作系统,内存泄漏仍然相关吗?

4
如果你的操作系统是64位的,那么你拥有的地址空间大小几乎是无限的。所以我的问题是,在这种系统上释放内存重要吗?即使你只有4GB的有限RAM,在需求分页方案中(只有在被访问时才会加载内存),与释放内存相比,你可能得到一些额外的页面交换开销。由于长时间不访问的内存将自动被交换。我在这里缺失了什么吗?或者我的论点是否正确?
实际上,如果它不会带来很大的性能损失,那么我认为对于C/C++程序员来说,这是一件好事,因为内存泄漏将不再是一个重要的问题!

4
当你增加内存时,内存泄漏崩溃应用程序的可能性就会降低,甚至整个机器都不太可能崩溃。但这并不意味着泄露内存是良好的实践。如果每个人都开始这样做,你可以想象会发生什么,这就是为什么它不是好的实践方式。很难看出这个问题的目的是什么。 - Cody Gray
你如何建议操作系统提前决定哪些内存将被送往清除区,哪些内存需要用于活动服务?它必须确保活动内存不会出现在你打算创建的无数浪费页面中的任何一个上,以免它花费大量时间不断地交换主要是死数据的页面。 - James Greenhalgh
8个回答

11

overhead(开销)...是几个额外的页面交换操作...因为内存...将自动被交换出去

自动被交换到哪里了?虚拟空间吗?页面文件是有限的,它们存在的存储也是有限的。

你认为在长时间运行的服务应用程序中永远不释放内存是一个好主意吗?


3
我认为关键词在于“虚拟”,其定义归结为“事实上不存在”。你有一块并非无限的内存空间。随着内存空间日益丰富,你能够不用过多关注内存管理的应用程序的范围也在扩大。
换句话说,如果你只是写一个“Hello World”的程序,那么当然可以不必清理内存垃圾。如今,你可能可以编写一个小型的应用程序,它不需要自己管理内存。但是,如果你编写了一个设备驱动程序或服务守护进程,并且预计要长时间运行,那么我可不想每周都得关掉生产机器手动清理其他人的内存泄漏问题。

我认为这里很多人都误读了问题。他并不是在暗示我们现在有足够的内存可以不用关心内存泄漏。他考虑的是一种情况,即应用程序不会释放内存,因为泄漏的内存最终会被系统分页出去,从而再次释放RAM。在32位系统上,进程很容易耗尽地址空间,在64位系统上,这个想法有一定的道理。 - zoul
2
@zoul,这样可以释放RAM并占用页面文件中的空间。但是,页面文件没有无限数量的内存页面可用。因此,在我看来,关于*virtual(ly)*语义学的帖子似乎并不错位。 - ta.speot.is

2

清理分配的内存是最佳实践,难道不是吗?

如果所有程序因为性能原因都停止释放内存块,你将会看到发生什么。

是的,这很重要。


1
是的,但我认为你不会有太多性能损失,这是我的问题。在实际情况下,这也可能很有用,因为内存泄漏不再是一个大问题! - MetallicPriest
2
“看看会发生什么”并不是一个理想的答案,因为这种情况很难再现。我相信发帖者对于会发生什么以及为什么会发生感兴趣。 - zoul
1
@MetallicPriest:如果内存大小相等,那么在64位系统上你会有与32位系统相同的性能损失。你认为这种差异应该从哪里产生? - vgru
Groo,在32位系统中,您只有4GB的地址空间,无法超过这个限制。 - MetallicPriest

2
这取决于应用程序。一些应用程序分配了大量内存(例如每秒几百兆字节)。如果您认为您永远不会释放它,而是使用交换空间,那么您将在几个小时内填满数千兆字节的交换空间。
请参阅有关垃圾回收的大量文献,例如《垃圾回收手册》
老的Andrew Appel的论文《垃圾回收可以比堆栈分配更快》应该能给您提供有趣的见解。
但是,您可以考虑一个泄漏很少的垃圾收集器,然后泄漏率只有几兆字节每分钟(在GC之后),情况就不同了。
当您仅考虑短寿命的应用程序时,内存泄漏确实不太重要。但是,一旦您拥有长时间运行的服务器进程,您就应该关注内存,并且永远不释放(或重复使用)它是一个坏主意。

1
你的数字 稍微 高估了一些。每秒分配100MB的程序在一个小时内分配大约350GB - 使用300 ("几百") MB/s和3小时 ("几个小时"), 你得到3 TB。你的交换空间有多大? ;) 当然,这只是一个虚构的例子,但我喜欢挑剔,而且用现实估计进行严谨的计算会更有说服力,我认为。 - user395760
但是现在3TB的交换空间已经非常巨大了。我没有足够的财力购买一个3TB的固态硬盘,甚至也没有足够的10KRPM硬盘(你总是希望快速交换!)来制作一个3TB的交换空间。请注意,我说的是以GB为单位的交换空间,而不是TB。 - Basile Starynkevitch

2

是的,对于生命周期短暂的工具(如命令行实用程序,例如ls),这样做是有意义的。

例如,Busybox 甚至有一个配置选项,用于控制是否像通常一样free内存或让操作系统在退出时自动清理它。

FEATURE_CLEAN_UP

作为一种大小优化,busybox 通常在退出时不显式释放动态分配的内存或关闭文件。这可以节省空间,因为操作系统会为我们清理,但它可能会使像valgrind这样报告大量内存和资源泄漏的调试器混淆。

除非您有一个真正好的手动清理东西的理由,否则不要启用此选项。


2
地址空间看起来可能是无限的,但当前计算机上的物理存储绝对不是。操作系统(任何操作系统,而不仅仅是Linux)无法知道应用程序是否完成了内存页面,除非它被明确释放。交换出的页面仍需要磁盘空间和CPU+I/O时间进行处理。
根据我的经验,即使在极少数情况下,某些精明的营销人员成功销售了超出要求的计算机系统,可用内存在一段时间后仍然成为一个问题。
此外,如果你想知道如果一个应用程序停止释放内存会发生什么,只需查看一个正在泄漏/过度使用内存而不是直接拒绝释放内存的应用程序。例如,经过几个小时的标签密集活动后,Firefox 在我的8GB系统上很快就会攀升到3GB以上。我甚至不敢想象如果没有释放任何内存,这个数字会变得多高。
现在想象一下,有十个应用程序同时做同样的事情 - 我自己的桌面系统上没有30GB的物理或虚拟内存。如果我的系统只有一个Firefox实例就已经在抖动,我害怕在你提出的方案中会发生什么...

是的,火狐团队显然已经开始应用提问者的逻辑了;这也是我很多版本前转向Chrome的一个重要原因。始终要问自己:“如果所有应用都这样做会怎么样?”它可以在Stack Overflow加载之前回答大多数问题。 - Cody Gray

1

如果你认为不释放内存最糟糕的事情就是程序崩溃,那么你还需要考虑一下以下后果:

  • 无法分配套接字缓冲区,导致数据包丢失。
  • 因为资源泄露而性能降低(这种情况始终存在)。
  • 你可能无法再产生调试/诊断日志或消息。
  • 文件描述符用尽。

总之,及时释放已分配的内存,这将有助于保持精神健康。


0
如果您有64位操作系统,则具有虚拟无限大小的地址空间。
您似乎忽略了其中的“虚拟”部分。
首先,您始终受到实际RAM的“限制”。
我的意思是如下所述: 在您提到的4GB示例中,如果没有进程释放内存并继续请求新内存,则操作系统将开始使用硬盘进行交换虚拟页面。
您将遇到页面错误和访问硬盘,这将对进程和整个系统产生严重的性能开销,如果所有正在运行的进程都发生这种情况(按照您认为可以接受的方法)。
因此,为了使用户拥有“可用”的系统,他必须购买更多的RAM。
如果您说,您的系统不响应,但您只需要购买更多的RAM,例如16GB或32GB或...,那么用户会有何反应?

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