gpt4 book ai didi

c# - 确定何时释放一些内存的简单算法.Net

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:01:16 24 4
gpt4 key购买 nike

我们的系统会保留大量大型对象以提高性能。然而,当内存不足时,我们想要删除一些对象。这些对象是有优先级的,所以我知道要丢弃哪些。有没有一种简单的方法来确定何时释放内存?此外,删除 1 个对象可能还不够,所以我想我需要一个循环来删除、检查、必要时再次删除等等。但是在 C# 中,我不一定会立即看到删除对象的效果,所以怎么做我避免踢出太多东西?

我想这只是已用内存与总物理内存和虚拟内存的简单函数。但是什么功能呢?

编辑:一些说明

  • “大对象”具有误导性。我的意思是对象的逻辑“包”(对象应该单独足够小以避免 LOB - 这当然是意图)一起很大(~100MB?)
  • 可能会收到要求使用此类软件包的请求。如果是在内存中,响应很快。如果没有,就需要重构,很慢。所以我想尽可能长时间地在内存中保留内容,但可以在必要时放弃请求最少的内容。
  • 我们没有合理的方法来序列化这些包。我们或许应该这样做,但工作量很大,而且这样做会遇到很多阻力。

我们最初的简单方法是定期将以下内容与可配置的阈值进行比较。

var c = new ComputerInfo();
return c.AvailablePhysicalMemory / c.TotalPhysicalMemory;

最佳答案

关于这个问题有很多不同的主题,我认为最好在实际回答之前弄清楚它们。

首先,您说您的应用确实掌握了很多“大对象”。定义大对象。任何大于 85K 的东西都会进入 LOH,它只会作为第 2 代系列的一部分(所有这些中最昂贵的)被收集,任何小于它的东西,即使你认为是一个“大”物体,也不会被处理与任何其他类型的对象一样。

其次在“管理内存”方面存在两个问题

  • 一个是管理您在虚拟内存空间中使用的空间量。也就是说,在 32 位系统中确保您可以寻址所有您要求的内存,这在 Windows 32 位系统中大约为 1.5 GB。
  • 其次是在需要时管理内存的处理,这是垃圾收集器工作的一部分,因此它会在内存不足时触发(尽管这并不意味着如果你不这样做,你就不会得到 OutOfMemoryException给 GC 足够的时间来完成它的工作)。

话虽如此,我认为您应该忘记取代 GC 的位置……让它完成它的工作,如果您担心,然后找到可能失败的关键路径(根据内存请求)并保护自己对抗 OutOfMemoryExceptions。

有许多不同的模式可用于处理您发布的案例,其中大部分实际上取决于您的业务场景。一个例子是有一个状态机实际上可以进入“OutOfMemory”状态,在这种情况下,系统会切换到释放内存,然后再做任何其他事情(包括处理旧对象和调用 GC 来清理所有东西,同时你耐心地等待它发生)。

其他技术涉及将数据保存到磁盘,然后在达到特定级别时根据某种算法手动换入和换出对象。这意味着停止所有线程(或一些线程,具体取决于业务)并来回移动数据。

如果你的大对象都是根据位置来控制的,你也可以在它们的创建上声明一个外观,这样外观就可以根据你的进程的内存量(虚拟内存)检查它是否需要释放对象正在使用。顺便说一句,使用其他答案中引用的 PerformanceInfo API 调用,因为这将包括非托管代码使用的内存量,尽管如此,它位于进程的虚拟内存空间内。

不要太担心“真实”内存,因为操作系统会确保最合适的页面位于内存中。

然后还有数百种其他优化,完全取决于您的业务场景。例如,数据库“知道”根据查询将数据存入内存,并提前预测您将要使用的数据,以便数据准备就绪,并且它们会删除未使用的对象……但这是另一个话题。

编辑:基于您对问题的编辑。

  • 检查外观中的内存不会增加显着的性能开销。
  • 如果内存开始不足,您应该决定要释放多少对象/多少空间。不要一次一个地收集,取一堆并释放足够的内存,这样您就不必再次收集。
  • 如果您采用之前的方法,您可以在释放足够的空间并继续在后台清理后处理请求。
  • 处理内存/磁盘交换的最快方法之一是使用 memory mapped files .

关于c# - 确定何时释放一些内存的简单算法.Net,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20001726/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com