gpt4 book ai didi

c# - .NET 空闲内存使用(如何防止过度分配/释放内存给操作系统)

转载 作者:可可西里 更新时间:2023-11-01 03:09:36 27 4
gpt4 key购买 nike

我目前正在开发一个网站,该网站大量使用缓存数据来避免往返。在启动时,我们得到一个“大”图(数百种不同类型的对象)。这些对象通过 WCF 检索并反序列化(我们使用 Protocol Buffer 进行序列化)我正在使用 redgate 的内存分析器来调试内存问题(内存似乎不适合我们在完成初始化并最终得到这份报告后“需要多少内存”

Global Report

现在我们可以从这份报告中收集到的是:

1) .NET 分配的大部分内存是空闲的(它可能在反序列化期间被正确分配,但现在它是空闲的,我希望它返回操作系统)

2) 内存碎片化(这很糟糕,因为每次我刷新现金时我都需要重做内存饥饿的反序列化过程,这反过来会创建大对象,由于碎片化可能会抛出 OutOfMemoryException)

3) 我不知道为什么空间是碎片化的,因为当我查看大对象堆时,只有 30 个实例,15 个 object[] 直接附加到 GC 而与我完全无关,1 是一个char 数组也直接附加到 GC 堆,剩下的 15 个是我的,但不是原因,因为如果我在代码中注释掉它们,我会得到相同的报告。

所以我的问题是,我该怎么做才能更进一步?我不太确定在调试/工具中寻找什么,因为我的内存似乎是零散的,但不是我的,大量的可用空间是由 .net 分配的,我无法释放。

此外,请确保您在回答之前很好地理解问题,我不是在寻找一种方法来释放 .net (GC.Collect) 中的内存,而是将 .net 中已经释放的内存释放到系统中以及对所述内存进行碎片整理。

请注意,缓慢的解决方案很好,如果可以手动对大堆进行碎片整理,我会全力以赴,因为我可以在 RefreshCache 结束时调用它,如果运行需要 1 或 2 秒也没关系。

感谢您的帮助!

一些我忘记的注意事项:1) 该项目是一个 .net 2.0 网站,我在 .net 4 池中运行它得到相同的结果,如果我在 .net 4 池中运行它并将其转换为 .net 4 并重新编译,则同上。

2) 这些是发布构建的结果,因此调试构建不是问题。

3) 这可能非常重要,我在 webdev 服务器中根本没有遇到这些问题,只有在 IIS 中,在 webdev 中我得到的内存消耗非常接近我的实际消耗(更多,但不是 5-多 10 倍!)

最佳答案

在大对象堆上分配的对象(对象 >= 85,000 字节,通常是数组)不会被垃圾收集器压缩。 Microsoft 认为移动这些对象的成本太高。

The recommendation is to reuse large objects if possible to avoid fragmentation on the managed heap and the VM space.

http://msdn.microsoft.com/en-us/magazine/cc534993.aspx

我假设您的大对象是由反序列化库创建的临时字节数组。如果库允许您提供自己的字节数组,您可以在程序开始时预先分配它们,然后重用它们。

关于c# - .NET 空闲内存使用(如何防止过度分配/释放内存给操作系统),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9805058/

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