注意:我知道问题Memory management in memory intensive application,但是这个问题似乎是关于频繁进行内存分配的应用程序,而我的问题是关于有意设计消耗尽可能多的应用程序物理记忆是安全的。
我有一个服务器应用程序,它使用大量内存来执行缓存和其他优化(想想SQL Server)。应用程序在专用计算机上运行,因此可以(并且应该)消耗尽可能多的内存,以便加速和增加吞吐量和响应时间,而无需担心影响系统上的其他应用程序。
问题在于,如果内存使用被低估,或者负载增加,最终可能会因为内存分配失败而导致令人讨厌的故障 - 在这种情况下,最好的做法是释放内存以防止故障以牺牲性能为代价。
一些假设:
我的问题是 - 我应该如何在这样的应用程序中处理内存分配?特别是:
核心目标是防止因使用太多内存而导致的失败,同时尽量占用尽可能多的内存。
我是一名C#开发人员,但我希望无论语言如何,任何此类应用程序的基本概念都是相同的。
答案 0 :(得分:1)
在linux中,内存使用百分比分为以下几个级别。
0 - 30% - 没有交换 30 - 60% - 仅交换脏页 60-90% - 交换干净页面也基于LRU政策。
90% - 调用OOM(内存不足)杀手并终止占用最大内存的进程。
检查一下 - http://linux-mm.org/OOM_Killer
在思考窗口中可能有类似的策略,因此您可以检查内存统计信息并确保永远不会达到最大阈值。
停止消耗更多内存的一种方法是进入休眠状态并为内存清理线程提供更多时间来运行。
答案 1 :(得分:0)
这是一个非常好的问题,并且也必须是主观的,因为C#基础的本质是所有内存管理都是由运行时完成的,即垃圾收集器。垃圾收集器是一个非确定性实体,它管理和扫描内存以进行回收,这取决于内存碎片化的频率,GC将启动因此提前知道并不容易。
正确管理内存听起来很乏味但常识适用,例如using
子句以确保对象被处置。您可以放入一个处理程序来捕获OutOfMemory Exception
,但这是一种尴尬的方式,因为如果程序内存不足,程序是否会抓住,炸弹,或者应该耐心等待GC启动,再次确定这很棘手。
系统的负载会对GC的工作造成不利影响,几乎到了拒绝服务的程度,因为机器的规格,或者机器的性质,所有东西都会停止运转。工作未知,我无法完全回答,但我认为它有大量的RAM ..
从本质上讲,虽然这是一个很好的问题,但我认为你不应该担心它并将其留给.NET CLR来处理内存分配/碎片,因为它似乎做得非常好。
希望这有帮助, 最好的祝福, 汤姆。
答案 2 :(得分:0)
你的问题让我想起旧的讨论"So what's wrong with 1975 programming ?"。 varnish-cache的架构师认为,你不应该告诉操作系统自行解决并管理所有内存,而应该与操作系统合作,让它理解你打算用内存做什么。
例如,您应该使用memory-mapped files而不是简单地从磁盘读取数据。这允许OS在内存变得稀缺时应用其LRU算法将数据写回磁盘。同时,只要有足够的内存,您的数据就会留在内存中。因此,您的应用程序可能会使用所有内存,而不会有被杀的风险。