3

在我做的项目中是内存泄漏。我重写了所有的函数来修复一些,但还剩下一个:

该程序有一个面板对象数组,每次我放入一个新面板时它都会增长。当它达到 400 个面板时,它会删除最旧的面板以释放一些内存。

我不明白的是:

tempPanels = new Panel[panels.Length];
Array.Copy(panels, 1, tempPanels, 0, panels.Length - 1);//delete the oldest history log (the first of the array)
panels = null; //empty object array
panels = new Panel[tempPanels.Length + 1]; //set new length
tempPanels.CopyTo(panels, 0);//restore panels

当我使用上面的代码时,内存使用量仍在不断增加......有人可以解释为什么我必须在将面板设置为空之前先处理面板吗?

tempPanels = new Panel[panels.Length];
Array.Copy(panels, 1, tempPanels, 0, panels.Length - 1);//delete the oldest history log (the first of the array)
panels[0].Dispose();
panels = null; //empty object array
panels = new Panel[tempPanels.Length + 1]; //set new length
tempPanels.CopyTo(panels, 0);//restore panels

提前致谢!

编辑@史蒂夫 B:
程序创建一个新面板:panel currentPanel;
当有一个新面板时,我声明 currentPanel:currentPanel = new Panel();
之后我调用此函数:setCurrentPanelConfiguration:

public void setCurrentPanel()
{
  currentPanel.Name = "panel" + panels.Length;
  currentPanel.Size = new System.Drawing.Size(485, 75);
  currentPanel.BackColor = Color.Transparent;
}

为了修复滚动错误,我使用了一个面板 HistoryPanel,我在其中放置了 currentPanel:

HistoryPanel.Controls.Add(currentPanel);

然后我添加所有控件:用户名、当前时间和头像。

为了保存面板,我在创建空间后将其添加到阵列面板中,如上所示:
panels[panels.Length-1] = currentPanel;

我使用数组是因为历史记录显示最新的数组。为此,每次我必须将所有面板向下移动 80 像素。

4

2 回答 2

11

Because setting something to null does not dispose of it, it just dereferences it - the garbage collector isn't monitoring your assignments to check for your null references, it does it when it wants (all else being equal) or when explicitly told to do so.

In short, because null and memory management are different things.

于 2013-01-08T09:02:29.130 回答
3

除了格兰特托马斯所说的,你为什么不使用List<Panel>更容易管理的 a 呢?

代码将如下所示(假设panels声明为List<Panel>):

Panel p = panels[0];
panels.RemoveAt(0);  // This removes the first element

p.Dispose(); // This disposes of the element

如果你想保留你的代码,它应该如下所示:

tempPanels = new Panel[panels.Length];
Array.Copy(panels, 1, tempPanels, 0, panels.Length - 1);//delete the oldest history log (the first of the array)

// Dispose of every element in the array
for (int i = 0; i < panels.Length; i++)
    panels[i].Dispose();

// The following line is unneccessary, as the variable is re-assigned anyway
// panels = null; //empty object array

panels = new Panel[tempPanels.Length + 1]; //set new length
tempPanels.CopyTo(panels, 0);//restore panels
于 2013-01-08T09:07:12.747 回答