1

我有一个 OOM 问题。我尝试使用 WinDbg 确定导致 OOM 异常的原因,但没有成功。

我有一个带有 Infragistics 超网格的 Windows 窗体,可以加载 11000 行。每行绘制一个删除位图。我无法在很多机器上重现它,但一个客户经常报告,所以我要求进行内存转储

我需要帮助才能走得更远。

我有一个大小 = 1.9 GB 的内存转储。

我按照以下步骤操作:

.loadby sos clr

!线程

线程

!pe 3c61f7d0

打印异常

!dumpheap -stat

转储堆统计

它似乎不是 OOM 的候选类型

我运行 !dumpheap -min 85000 -stat 来确定哪些对象使用了超过 85k 的内存,我得到了:

统计数据:

  MT      Count    TotalSize    Class Name

0028cd20 1 438732 免费

共有 1 个对象

!finalizequeue 完成队列 1 完成队列 2

4

2 回答 2

2
  1. 您是如何得出结论的,您遇到了 OOM 问题?例外?什么例外?调试器输出?什么调试器输出?

  2. 1.9 GB 的内存转储非常大。这使得您的 OOM 很可能是由内存不足引起的.....在您大喊之前还有其他事情会引发 OutOfMemory 异常。

  3. 如果没有超过 85k 的托管对象,那么它要么是非托管内存,要么是大量小于 85k 的对象。例如,这可以是地图、链表或树或类似的,或者您自己的对象层次结构。

  4. 如果它是非托管内存,那么最佳候选者肯定是位图。加载 11000 个位图似乎不是一个非常好的主意。我建议你不要那样做——为什么不使用“x”或类似的东西呢?

还有,有什么作用Resources.Resources.delete?它看起来像一个属性get,但它是每次都加载位图,还是加载一次并使用同一个?如果它每次都加载它,那么......不要。如果它重用它,则表明网格正在为每一行创建一个新的,它真的不应该这样做。

于 2013-07-22T14:00:46.807 回答
0

问题是我如何配置 Infragistics 网格。答案也记录在此链接中:

http://www.infragistics.com/community/forums/t/56315.aspx

导致OOM问题的代码是:

private static void ConfigureDeleteColumnOn(UltraGridBand band)
{
    band.Columns.Add(DELETE_BUTTON);
    band.Columns[DELETE_BUTTON].EditorControl = GetDeleteButtonEditor();
}

private static Control GetDeleteButtonEditor()
{
    UltraTextEditor editor = new UltraTextEditor();
    EditorButton btn = new EditorButton
                        {
                            Appearance =
                                {
                                    Image = Resources.Resources.delete,
                                    ImageBackgroundStyle = ImageBackgroundStyle.Centered
                                }
                        };
    editor.EditorButtonClick += editor_EditorDeleteButtonClick;
    editor.ButtonsLeft.Add(btn);
    return editor;
}

此代码强制网格为每个单元格创建一个新的位图。有 11000 行,网格尝试创建 11000 个位图并导致 OOM 异常。

解决方案是:

private static void ConfigureDeleteColumnOn(UltraGridBand band)
{
    band.Columns.Add(DELETE_BUTTON);
    band.Columns[DELETE_BUTTON].ButtonDisplayStyle = ButtonDisplayStyle.Always;
    band.Columns[DELETE_BUTTON].Style = ColumnStyle.Button;
    band.Columns[DELETE_BUTTON].CellButtonAppearance.Image = Resources.Resources.delete;
}
于 2014-05-07T10:57:27.380 回答