为什么同一页面的每个页面加载后内存使用量都会增加

我有一个简单的视图来显示大约 2000 个客户(尚未寻呼,这是我流程的下一步)。


这是我的控制器部分:


public class CustomersController : Controller

{

    private readonly MyModel _context;


    public CustomersController(MyModel context)

    {

        _context = context;

    }

 // GET: Customers

    public async Task<IActionResult> Index()

    {

        var customers = await _context.Customers.ToListAsync();

        return View(customers);

    }


}

和一个简单的视图:


@model IEnumerable<Customer>


  @{ ViewData["Title"] = "Index"; }


  <table class="table">

    <thead>

      <tr>

        <th>

          @Html.DisplayNameFor(model => model.Name)

        </th>

        <th></th>

      </tr>

    </thead>

    <tbody>

      @foreach (var item in Model) {

      <tr>

        <td>

          @Html.DisplayFor(modelItem => item.Name)

        </td>

      </tr>

      }

    </tbody>

  </table>

每当我刷新页面(返回相同的结果集)时,进程内存每次都会增加 20 到 30 MB。


下面是内存诊断的屏幕截图:快照 1 在第一页加载之前;快照 2 是在第一页加载之后;快照 3 是同一页面数十次重新加载后的结果...

https://img2.mukewang.com/650fffef00016ff213980811.jpg

我认为内存会保持不变,因为 DbContext 应该在每次请求时被释放,不是吗?

我做错了什么以及如何控制内存使用?


阿波罗的战车
浏览 127回答 2
2回答

qq_花开花谢_0

我认为您对垃圾收集器的目的有一些误解。其目的不是为了最小化内存使用;而是为了减少内存使用。相反,它是为了确保您的进程有可用的内存。这是一个重要的区别。垃圾收集器将定期清理内存中不再使用的对象,并将它们标记为要收集。稍后,当 GC 检测到内存不足时,它将激活并:移动东西,这样你就有更少的小内存块和更多的大内存块(内存只能在连续的块中分配)。收集对象并释放它们的内存。它将很少运行。可以对其进行配置,以根据特定要求定制 GC,但很少需要这样做。每次 GC 运行时,它都会尽可能少地执行操作以确保您的程序拥有所需的内存。这样做是因为垃圾收集成本高昂,并且可能导致明显的性能峰值。处置一个对象并不意味着“立即摆脱它并释放其内存”。意思是“我不再使用这个了,所以你可以在方便的时候清理它。”&nbsp;(软件太有礼貌了!)因此,处理上下文不会立即减少内存使用量。可以向 GC 发出非常强烈的提示,表明您想要收集,但很少需要且不建议这么做。所以,你的 GC 会等待。它会等待时机,直到检测到“嘿,我们内存不足!”&nbsp;然后,也只有到那时,它才会检查您的进程是否有无法收集的对象。因此,当您的内存消耗开始超过进程可用的内存时,您可以预期 GC 将会运行。然后,它将尽快释放内存。它的目标只是确保您的进程有可用的内存。那么,您可以期待观察到什么?你的进程内存会像过山车一样上下波动。它上涨的频率会比下跌的频率更高。您的进程内存使用量将趋向于最大可用内存,并且通常只会在接近限制时才会下降。集合不会频繁发生(根据需要),并且大小可能相差很大。我认为您无需担心任何事情,并且建议您仅在开始出现内存不足错误时才担心内存使用情况。

宝慕林4294392

您实际上可以使用 MemoryDiagnoser 查看内存使用情况和 GC 收集的情况。我建议使用 GcMode Server 为 TRUE,因为它将更好地向您展示 GC 如何在服务器上而不是在本地工作站上工作。我知道学习如何使用它很麻烦,但经过一段时间后,这是非常值得的。在 VS 中查看内存使用情况的问题是因为它处于调试模式,而这并不完全是您的代码在发布时的行为方式。
打开App,查看更多内容
随时随地看视频慕课网APP