分配内存,如果需要,可以被操作系统释放

4
我正在编写一个程序,为大型文档中的每一页生成缩略图。出于性能考虑,我想尽可能长时间地将缩略图保留在内存中,但如果操作系统决定有其他更重要的用途(例如用户开始运行不同的应用程序),我希望它能够重新获取这些内存。
如果内存消失了,我可以随时重新生成缩略图。
有没有跨平台标记内存为“可在需要时删除”的方法?该程序使用C++编写。
编辑:为了澄清,与其在内存不足时得到通知或定期监视系统的内存量,我更倾向于分配内存,然后在它不使用时“解锁”它。然后,如果需要,操作系统就可以窃取未锁定的内存(即使是磁盘缓冲区,如果它认为那是更好的内存使用),作为程序员,我只需要在再次使用它之前“锁定”内存。如果锁定失败,则说明内存已被重新用于其他用途,因此我需要重新生成缩略图;如果锁定成功,则可以继续使用以前的数据。
原因是我可能在屏幕上显示大约20页文档,但我可能会保留其他200页的缩略图以防用户滚动一下。但是,如果他们有一段时间不使用,那么该内存可能更好地用作磁盘缓存或用于存储网页之类的内容,因此我希望能够告诉操作系统如果需要,可以重新使用我的一些内存。
必须监视系统范围内的可用内存量可能无法达到目标(我的内存永远不会被回收以改善磁盘缓存),并且在低内存通知方面也只有在紧急情况下才有所帮助。我希望通过具有锁定和解锁方法来轻松实现这一点,并在非紧急情况下提高系统性能。

只是为了澄清,与其在内存不足时收到通知或定期监视系统的内存量,我更倾向于分配内存,然后在不使用时“解锁”它。除了在内存不足的情况下释放内存之外,还有什么好处?如果内存不低,为什么操作系统/另一个应用程序不会为自己的缓存目的占用更多内存?这似乎是过早优化的情况。 - ta.speot.is
1
假设你有4GB的RAM并且缩略图占用了1GB。那么有足够的空闲内存,一切都很好。但如果你使用只有2GB RAM的系统,使用1GB缩略图可能还可以接受,如果这是唯一运行的应用程序的话。但由于可用内存非常少,如果你打开一个web浏览器,操作系统能够回收整个1GB将会很好。 - Malvineous
4个回答

4
有没有跨平台的方法来标记内存,以便在需要时可以删除?该程序使用C++编写。
对于至少在Windows上,您可以注册内存资源通知
HANDLE WINAPI CreateMemoryResourceNotification(
  _In_  MEMORY_RESOURCE_NOTIFICATION_TYPE NotificationType
);

NotificationType

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

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


在哪些物理内存范围内,两个通知都会被触发? - user3004790

2
在AIX中,当可用内存不足时,会向应用程序发送一个名为SIGDANGER的信号。您可以处理此信号并释放一些内存。
Linux人员正在讨论将此功能实现到Linux中。但据我所知,它尚未在Linux中实现。也许他们认为应用程序不应该关心低级别的内存管理,可以通过交换在操作系统中透明地处理。
在posix标准中,有一个函数posix_madvise,可以将内存区域标记为不太重要。其中有一个建议POSIX_MADV_DONTNEED,指定应用程序预计在不久的将来不会访问指定范围。
但不幸的是,当前的Linux实现将立即释放调用此建议的内存范围。
因此,没有通用的解决方案来回答您的问题。
但是,在几乎所有操作系统上,您都可以通过某些操作系统接口读取当前可用内存。因此,您可以定期读取这样的值,并在操作系统中可用内存不足时手动释放内存。

你确定吗?也许你和madvise()+MADV_DONTNEED混淆了,在Linux中,实际上会释放指定的页面,而posix_madvise()+POSIX_MADV_DONTNEED不会释放页面,但它会将内存保留给用户。 - Marco Pagliaricci

0

你不需要特别的去做什么。如果一些东西最近没有被使用,操作系统会自动将它们从内存中清除掉。有些操作系统可能有特定的方式去优化这个过程,但通常情况下,不需要额外的操作。


1
操作系统会自动从内存中删除最近没有使用的内容。我猜你指的是页面文件。听起来OP想在影响整个机器性能之前生成尽可能多的缩略图。但如果他什么也不做,那么他只会填满页面文件。 - ta.speot.is
@ta.speot.is: 可能他在一台配有充足页面文件的服务器级机器上。如果他想要,他可以拥有可配置的限制,没有应用程序的具体细节,很难确定。 - David Schwartz

0

这个问题非常相似,而且有答案涵盖了这里没有涉及的内容。 在Linux中分配“临时”内存

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

所有自动释放缓存空间的基本知识都已经存在于任何具有磁盘缓存的操作系统中,很难想象没有API可以为此提供支持,特别是在移动Web浏览器等方面,这将产生巨大的差异。


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