【问题标题】:Allocating memory that can be freed by the OS if needed如果需要,分配可由操作系统释放的内存
【发布时间】:2013-06-08 00:57:24
【问题描述】:

我正在编写一个程序,它为大型文档中的每一页生成缩略图。出于性能原因,我希望尽可能长时间地将缩略图保留在内存中,但我希望操作系统能够回收该内存,如果它决定它还有另一个更重要的用途(例如,用户已经开始运行不同的应用程序。)

如果记忆消失了,我总是可以稍后重新生成缩略图。

是否有任何跨平台方法可以将内存标记为需要时可以删除?该程序是用 C++ 编写的。


编辑:只是为了澄清,而不是在内存不足时收到通知或定期监视系统的内存量,我更多地考虑分配内存,然后在不使用时“解锁”它。然后操作系统可以在需要时窃取未锁定的内存(即使是磁盘缓冲区,如果它认为这样可以更好地利用内存),作为程序员,我所要做的只是在我打算使用之前再次“锁定”内存.如果锁定失败,我知道内存已被其他用途重用,因此我需要重新生成缩略图,如果锁定成功,我可以继续使用之前的数据。

原因是我可能会在屏幕上显示一个文档的 20 页,但我最好保留其他 200 页左右的缩略图,以防用户滚动一下。但是如果他们去做其他事情一段时间,那块内存可能会更好地用作磁盘缓存或存储网页或其他东西,所以我想能够告诉操作系统它可以重用我的一些内存,如果它想要。

必须监控系统范围内的可用内存量可能无法实现目标(我的内存永远不会被回收以改善磁盘缓存),并且获得低内存通知只会在紧急情况下有所帮助。我希望通过锁定/解锁方法,这可以以更轻量级的方式实现,并有利于系统在非紧急情况下的性能。

【问题讨论】:

  • 只是为了澄清,而不是在内存不足时收到通知或定期监视系统的内存量,我更多地考虑分配内存,然后在何时“解锁”它它没有被使用。 除了在内存不足的情况下,释放内存有什么好处?如果内存不低,为什么操作系统/另一个应用程序不为自己的缓存目的占用更多空间?这似乎是过早优化的情况。
  • @ta.speot.is:假设你有 4GB RAM,而缩略图占用 1GB。然后有足够的可用内存,所以一切都很好。但是想象一下,您在一个只有 2GB RAM 的系统上。如果这是唯一运行的应用程序,则使用 1GB 的缩略图可能没问题,但由于可用内存非常少,如果操作系统可以收回整个 1GB,例如,如果您加载 Web 浏览器,那就太好了。跨度>

标签: c++ caching memory-management


【解决方案1】:

是否有任何跨平台方法可以将内存标记为需要时可以删除?该程序是用C++编写的

至少对于 Windows,您可以register for a memory resource notification

HANDLE WINAPI CreateMemoryResourceNotification(
  _In_  MEMORY_RESOURCE_NOTIFICATION_TYPE NotificationType
);

NotificationType

  • LowMemoryResourceNotification 可用物理内存不足。
  • HighMemoryResourceNotification 可用物理内存很高。

请小心响应两个事件。您可能会创建一个反馈循环(内存不足,释放缩略图!然后内存高,制作所有缩略图!)。

【讨论】:

  • 发出两个通知的物理内存范围是多少?
【解决方案2】:

在 AIX 中,当可用内存不足时,会向应用程序发送一个信号 SIGDANGER。你可以处理这个信号并释放一些内存。

Linux 人员正在讨论将此功能实现到 Linux 中。但是 AFAIK 它还没有在 Linux 中实现。也许他们认为应用程序不应该关心底层内存管理,它可以通过交换在操作系统中透明地处理。

在 posix 标准中,有一个函数 posix_madvise 可用于将内存区域标记为不太重要。有一个建议POSIX_MADV_DONTNEED 指定应用程序期望它在不久的将来不会访问指定的范围。

但不幸的是,当前的 Linux 实现将在使用此建议调用 posix_madvise 时立即释放内存范围。

因此,您的问题没有可移植的解决方案。

但是,在几乎每个操作系统上,您都可以通过某些操作系统接口读取当前可用内存。因此,当操作系统中的可用内存不足时,您可以定期读取这些值并手动释放内存。

【讨论】:

  • 你确定吗?也许你对madvise()+MADV_DONTNEED 感到困惑,事实上,它在 Linux 中会释放你指定的页面,而posix_madvise()+POSIX_MADV_DONTNEED 不会释放页面,但它会将内存完整地留给用户
【解决方案3】:

您无需做任何特别的事情。如果最近没有自动使用过,操作系统会从内存中删除它们。一些操作系统有特定于平台的方法来改进这一点,但通常不需要什么特别的。

【讨论】:

  • 如果最近没有使用过,操作系统会自动从内存中删除它们。我假设你的意思是页面文件。听起来 OP 想要在影响整个机器的性能之前生成尽可能多的缩略图。但如果他没有什么特别的,那么他只会填满页面文件。
  • @ta.speot.is:大概他在服务器级机器上,有大量页面文件。如果他愿意,他可以有一个可配置的限制,如果不猜测他的应用程序的细节就很难说。
【解决方案4】:

这个问题非常相似,并且其答案涵盖了此处未涵盖的内容。 Allocating "temporary" memory (in Linux)

这不应该太难做,因为这正是页面缓存所做的,使用未使用的内存来缓存硬盘。理论上,有人可以编写一个文件系统,当你从某个文件中读取时,它会计算一些东西,然后页面缓存会自动缓存它。

自动释放缓存空间的所有基础知识已经存在于任何具有磁盘缓存的操作系统中,而且很难想象没有 API 可以产生巨大的差异,尤其是在移动网络浏览器等方面。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-06
    • 1970-01-01
    • 1970-01-01
    • 2012-04-05
    • 2017-07-11
    • 2015-05-03
    • 2010-11-17
    • 2012-10-29
    相关资源
    最近更新 更多