当内存限制接近时转储缓冲数据

时间:2011-03-08 21:30:40

标签: c++ windows linux macos memory-management

我的应用程序在后台缓冲可能的请求数据。目前,我基于命令行参数限制缓冲区的大小,并在达到此限制时开始转储较少使用的数据。这并不理想,因为它依赖于用户指定性能关键参数。有没有更好的方法来处理这个?有没有办法在系统开始抖动之前自动监视系统内存使用并转储最旧/最近最少使用的数据?

这里的一个复杂因素是我的应用程序在Linux,OSX和Windows上运行。但是我会在一个平台上做一个很好的方法来做到这一点。

5 个答案:

答案 0 :(得分:1)

您最好的选择可能是监控您的应用程序工作集/驻留集大小,并尝试在分配后不会增长时作出反应。关于要寻找什么的一些指示:

  • Windows:GetProcessMemoryInfo
  • Linux:/ proc / self / statm
  • OS X:task_info()

Windows还有GlobalMemoryStatusEx,它为您提供了一个很好的可用物理内存数字。

答案 1 :(得分:1)

我喜欢你目前的解决方案。让用户决定是好的。并不是每个人都希望缓冲区尽可能大,不是吗?如果您确实投资实现某种内存监视器以自动调整缓冲区/缓存大小,至少让用户在用户设置限制和自动/动态之间进行选择。

答案 2 :(得分:1)

我知道这不是一个直接的答案,但我会说退一步,也许不要这样做。

即使你有API来查看当前的物理内存使用情况,这还不足以选择理想的缓存大小。这取决于程序和机器(以及运行该程序的所有客户端的整个系统+他们正在查询的服务器)的典型和未来工作负载,平台的缓存行为,系统是否应该调整吞吐量或延迟等等。在紧张的内存情况下,您将与其他机会缓存竞争内存,包括操作系统的磁盘缓存。一方面,您希望对它们施加一些压力,以强制推出其他低价值数据。另一方面,如果你在有足够的内存时变得贪婪,那么你将会影响其他自适应缓存的行为。

使用推测性缓存/预取,LRU值函数是奇数:您将(希望)首先获取最可能被调用的数据,稍后获取可能性较小的数据,因此预取中的LRU数据缓存可能没有旧数据那么有价值。这可能会通过人为地“加热”不太常用的数据而导致系统范围的缓存中的反常行为。

您的程序似乎不太可能比简单的固定大小更好地选择缓存大小,可能会根据计算机上整体物理内存的大小进行缩放。并且它几乎没有机会击败了解机器典型工作负载及其性能目标的系统管理员。

使用自适应缓存大小调整策略意味着您的程序的资源使用将变为可变且不可预测。 (关于内存和用于填充预取缓存的I / O和服务器请求。)对于许多服务器情况,这并不好。 (特别是在HPC或DB服务器中,这听起来像它可能适用,或者是高利用率/高吞吐量环境。)一致性,可配置性和可用性通常比最大化资源利用率更重要。并且参考的位置往往会迅速下降,因此您可能会在缓存大小较大的情况下获得非常低的回报。如果这将用于服务器端,至少保留用于显式控制高速缓存大小的选项,并且可能使其成为默认选项(如果不是唯一的选项)。

答案 3 :(得分:-1)

有一种方法:它被称为虚拟内存(vm)。列出的所有三个操作系统都将使用虚拟内存(vm),除非没有硬件支持(在嵌入式系统中可能是这样)。所以我假设存在 vm 支持。

以下是Varnish项目架构说明的引用:

  

真正简短的回答是计算机不再有两种存储方式。

我建议你阅读全文:http://www.varnish-cache.org/trac/wiki/ArchitectNotes

这是一个很好的阅读,我相信会回答你的问题。

答案 4 :(得分:-1)

您可以尝试分配一些大容量的内存块,然后检查内存分配异常。如果发生异常,请转储数据。问题是,这只有在达到所有系统内存(或进程限制)时才有效。这意味着您的应用程序可能会开始交换。

try {
  char *buf = new char[10 * 1024 * 1024]; // 10 megabytes
  free(buf);
} catch (const std::bad_alloc &) {
  // Memory allocation failed - clean up old buffers
}

这种方法的问题是:

  1. 耗尽系统内存可能会造成危险并导致随机应用程序关闭
  2. 更好的内存管理可能是更好的解决方案。如果有可以释放的数据,为什么它还没有被释放?是否有可以运行的定期流程来清理不需要的数据?