我有一个应用程序,它定期需要使用计算上无关紧要的算法处理大块数据。事实证明,我还可以通过将数据块保存在内存缓存中来防止系统从硬盘访问中减慢速度。该应用程序是一个低优先级的应用程序,所以我正在努力减少它对系统的影响,这意味着使用额外的内存(如果可用)来减少CPU和硬盘驱动器的负载。缓存的数据只有64MB的字节块,而我在内存中的数据越多,程序在驱动器上的开销就越少。
我需要做的是在系统上的任何其他应用程序需要比可用物理内存更多的物理内存时转储内存缓存,并且这样做的速度足够快,以至于用户从不会因为高内存需求而感觉系统速度变慢。
我对如何在.NET应用程序中实现这一点特别感兴趣。
答案 0 :(得分:2)
一种选择是使用ASP.NET Cache,它可以清除项目以响应内存不足。虽然微软发出了一个警告,即只在ASP.NET应用程序中进行测试,但没有什么可以阻止你在任何应用程序中访问HttpRuntime.Cache
,而在实践中它已经在我完成时工作了。
如果感觉肮脏和错误(或者只是不能满足您的需求),我们至少可以从ASP.NET知道清除缓存的方式中汲取灵感。它会定期调用内核的GlobalMemoryStatusEx来查找可用的内存。具体而言,返回结构的 dwMemoryLoad 属性是正在使用的总内存的百分比。默认情况下,ASP.NET认为当内存达到90%时,内存将耗尽。
有一些示例代码可以自己调用here。
答案 1 :(得分:1)
您可以使用LowMemoryResourceNotification选项P / Invoke到Win32 CreateMemoryResourceNotification API。这将返回一个通知对象,您可以轮询(使用QueryMemoryResourceNotification)或等待(在后台线程中;您需要使用其中一个Win32等待方法而不是.NET等待方法,或者可能从中派生自定义类WaitHandle封装Win32对象)。您可以通过从缓存中删除块并强制进行垃圾回收来做出响应;你必须测试这是否“足够快以至于用户永远不会觉得系统变慢。”
另外,查看文档时,提出低内存通知的阈值是真正低内存(4 GB系统上为32 MB!)。我怀疑到那时用户可能已经感觉到了减速,并且将应用程序分页到内存中以转储其块可能会导致可察觉的磁盘访问。同样,您可以通过测试对此进行评估。
答案 2 :(得分:-1)
您可以使用WeakReference类对内存块进行弱引用。这允许垃圾收集器在必要时删除对象。
Yor对象将位于大对象堆中,因为它们大于85 kb。最常见的垃圾收集只查看第一代堆,因此它不会收集您的对象。如果系统通知.NET系统内存不足,则垃圾收集器将运行更彻底的集合,删除大对象堆中的对象。