【问题标题】:Library for defragmenting memory用于对内存进行碎片整理的库
【发布时间】:2009-12-08 20:50:59
【问题描述】:

有谁知道用于对 Windows 2003 服务器的内存进行碎片整理的 dll 吗?

这是背景: 我们有一个 .net 电子商务网站,它使用预制框架完成大部分繁重工作。在将对象添加到缓存时尝试分配内存时,网站偶尔会出现内存不足的异常。它主要发生在框架尝试将大型数据集添加到缓存时。

我了解当您尝试向缓存添加内容时,它需要使用连续内存来添加对象,如果找不到足够大的内存块,您将收到内存不足异常。

当 IIS 已经消耗 600MB 以上的内存并且需要多出 10 或 20MB 时,服务器经常会遇到这个问题。服务器有 4GB 的内存,所以 IIS 应该能够使用 2GB,但我认为是这些大对象有问题找到合适的地方。所以我的 hacky 解决方法是尝试捕获异常,运行快速 RAM 碎片整理,然后继续。

我知道最好使用更小的对象,但我真的不想对框架进行逆向工程来替换部分缓存代码。

干杯, 兰斯

【问题讨论】:

  • 还有什么其他程序在后台运行?
  • 我不确定您的假设是否正确。我记得它的方式,你看到的内存是由 4K 块组装而成的,所以它不需要在操作系统级别是连续的。在局部治疗水平上,它很可能需要,但这完全是另一回事。
  • 我在过去的项目中遇到过类似的问题,这与背景中的内容几乎无关。从 MS 工程师告诉我的情况来看,这更多是 .net 中的问题,而不是 Windows 中的问题。释放后台操作会有所帮助,但作用很小。我们的回答是对内存使用更加小心,但这听起来不适合您。它也是一个 winform 应用程序,所以我们不必担心 24x7 的操作。我知道这没什么帮助,但希望至少能过滤掉你会得到的一些回复。

标签: c# asp.net windows memory


【解决方案1】:

首先,内存的物理结构不需要碎片整理——操作系统管理物理内存的页面并将其作为连续的 2GB 地址空间呈现给应用程序。然后如何管理此内存取决于应用程序(或 .NET 应用程序中的 CLR)

大多数 CLR 中的 GC(我相信 .NET 4.0 CLR 在这方面做出了一些改变)对大对象堆使用传统的“链表”分配,它不会压缩堆,因为移动大量内存的成本。

这意味着,如果您要分配大量具有不同大小不同生命周期的大型对象,您很容易以碎片化内存和内存不足异常告终。见过。

我从未见过内存“碎片整理程序”DLL 能够做到这一点,您必须完全控制 GC 和 CLR 以确保它更新任何引用。

值得尝试的两件事是:

1) 如果您可以从缓存中清除对象,那么当您遇到内存不足异常时,请释放一些对象。

2) 尝试 .NET 4.0 CLR 看看是否能改善这种情况。

【讨论】:

  • @Matt - 清除缓存确实可以阻止异常的发生。但这当然意味着您已经清除了缓存,消除了缓存的一些速度优势。我们使用的框架不支持 .net 4,所以这不是一个选项。我知道碎片整理是一个糟糕的选择,但在我最终重写框架的缓存方法之前,这是我能想到的最小侵入性的事情!
  • 正如我所说,您必须完全控制 CLR 和垃圾收集器才能对内存进行“碎片整理”。你能清除一些缓存吗(可能基于上次使用的基础?)
【解决方案2】:

在您开始设计解决方案之前,我建议您花一些时间来更好地了解该问题。一个好的起点是CLR profiler。它将让您了解内存分配和垃圾收集器的情况。

可能是 GC 无法跟上内存分配。 GC 通常会负责保持内存空间整洁,包括碎片整理。根据您的发现,您可能需要手动 trigger the GC

【讨论】:

    【解决方案3】:

    这篇文章应该有你需要的一切:

    http://msdn.microsoft.com/en-us/magazine/cc163528.aspx 例如:“碎片是托管堆上的问题吗?”

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-13
      • 1970-01-01
      • 2021-01-07
      • 2018-01-03
      • 1970-01-01
      • 2019-02-25
      • 1970-01-01
      • 2016-03-12
      相关资源
      最近更新 更多