【问题标题】:C# Simple garbage collection code not workingC# 简单的垃圾回收代码不起作用
【发布时间】:2021-01-07 07:45:49
【问题描述】:

我有一个简单的 WPF 应用程序,它分配内存、清除内存并与垃圾收集器交互。不幸的是,我永远看不到收集的垃圾会自动清除内存。例如,假设我单击 Alloc 按钮 10 次它分配一个 gig,然后如果我单击 New 按钮分配的内存不会下降。但是,如果我使用 GC.Collect (GC 按钮)强制进行垃圾收集,它会释放内存。我已经启用了 gcAllowVeryLargeObjects 设置为 true 的大型集合,因为我想使用超过 2 个演出进行测试。知道如何让垃圾收集器自动收集和释放内存吗?

简单代码摘录:

List<byte[]> m_allocs = new List<byte[]>();

private void AllocClick(object sender, RoutedEventArgs e)
{
  int oneHundredMegsAsBytes = 100000000;
  byte[] array = new byte[oneHundredMegsAsBytes];
  Array.Clear(array, 0, oneHundredMegsAsBytes);
  m_allocs.Add(array);
}

private void NewClick(object sender, RoutedEventArgs e)
{
  m_allocs = new List<byte[]>();
}

private void ClearClick(object sender, RoutedEventArgs e)
{
  m_allocs.Clear();
}

private void GCClick(object sender, RoutedEventArgs e)
{
  GC.Collect();
  GC.WaitForPendingFinalizers();
  GC.Collect();
}

【问题讨论】:

  • 如果操作系统仍有足够的可用内存,GC 会尝试不运行,因为它不需要运行。但是,您的示例中的 Array.Clear() 什么都不做 - 它只是将数组的内容设置为数组元素类型的默认值;在您的情况下,为零-但数组已经包含所有零。它不会改变数组的大小。
  • 垃圾收集发生在在某个未指定的时间点,或者如果有足够的内存则可能永远不会发生。它不会急切地尽早释放内存。
  • 并且,请记住,存在 GC 的全部原因是让开发人员不必担心管理内存。您无需测试 GC,它确实有效。

标签: c# garbage-collection


【解决方案1】:

你没有。

GC 已开发为仅在需要时运行。如果你的没有运行,那么它不需要。

你不想这样。

GC 很昂贵,GC 必须停止程序并弄清楚需要什么和不需要什么。如果它在每个周期结束时都这样做,您的程序就会变得一团糟。

但是...

您可以将the high-memory percent 更改为较低的值,这将使GC 变得更积极、更早。 这可能弊大于利

【讨论】:

    【解决方案2】:

    根据您的 cmets 提供的新信息进行试验时,我找到了解决方案。如果我多次按 alloc,例如直到使用 10 gig,然后单击 clear 并继续分配更多,它最终会将内存使用量降低到较低的值,例如 2 gig。

    所以垃圾收集器会自动运行示例代码,它只会在内存使用率高于我测试的内存使用率并且进一步分配有帮助时工作。

    【讨论】:

      猜你喜欢
      • 2011-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-29
      • 2021-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多