【问题标题】:Strategy for memory consumption management内存消耗管理策略
【发布时间】:2016-09-24 16:18:34
【问题描述】:

我们正在设计一个从后端缓存大量数据的企业应用程序。用户可以打开任意数量的应用程序窗口,每个应用程序窗口加载自己的数据并缓存。为了以某种方式管理内存消耗并防止整体操作系统性能下降,我们决定编写一个缓存管理器,它会自动监控应用程序的内存占用并在需要时从缓存中删除数据。

所以问题是我们很难确定是否是时候释放内存了。目前我们使用一种非常简单的方法——当应用的内存使用量超过物理内存的 80% 时,我们就开始从缓存中丢弃东西。

是否有任何(替代方案?)处理此类问题的既定做法?

【问题讨论】:

    标签: c# .net memory memory-management clr


    【解决方案1】:

    这基本没问题。没有真正好的策略。如果有多个竞争应用程序,这可能会导致缓存竞争和错误驱逐。

    如果您选择的阈值太低,则会浪费缓存空间。如果它太高,那么内存中就没有其他东西了,包括文件缓存、DLL、...

    “可用物理内存”是什么意思?你的意思是安装的内存还是免费的内存?应用程序如何使用 80% 的可用内存?我不清楚您使用的定义。

    SQL Server 一直使用内存,直到操作系统发出内存不足的信号(我相信当 95% 的“某物”正在使用时会发生这种情况)。

    您当然不想使用 GC 来释放内存。它通常会杀死你的整个缓存。

    也许您可以将缓存内容完全移动到磁盘?或者,您可以通过隐藏的缓存服务器进程在 .NET 进程之间共享缓存,该进程可以被应用进程查询。


    我想强调的是,如果您的应用程序消耗了 99% 的已安装 RAM(例如),性能将非常糟糕,因为文件缓存几乎是空的。这意味着即使是 DLL 和 .NET NGEN 的代码也会被频繁地调出和调入。

    也许更好的策略是假设需要 1GB 来适当地缓存操作系统和应用程序文件。因此,您可以消耗内存,直到安装的 RAM 中只有 10% 的空闲空间减去 1 GB。

    【讨论】:

    • 可用物理内存是指可用的内存。我知道在及时对象解除分配方面不能完全信任 GC,但到目前为止,在我们的测试中它还不是问题。此外,单独的窗口托管在单个窗口进程中,因此无需担心它们之间共享缓存。操作系统如何发出内存不足的信号?有没有办法在 .Net 中截获该信号?
    • 有一个 API:msdn.microsoft.com/en-us/library/windows/desktop/… 但 Windows 认为“低”的可能不是您想要的。这是一个任意阈值。如果您说“我们消耗了高达 80% 的空闲内存”,则该内存不再是空闲的。所以这个定义没有意义。您正在通过消耗内存来改变分母。
    • 对不起,我对内存使用声明不好。我在问题中更正了它。
    • +1 到“也许更好的策略是假设需要 1GB 来适当地缓存操作系统和应用程序文件。因此您可以消耗内存,直到安装的 RAM 只有 10% 可用负 1 GB。”这听起来像是给自己一些缓冲空间的好方法。