C#对象数组=null,不';t释放内存

本文关键字:释放 内存 数组 对象 null | 更新日期: 2023-09-27 17:51:07

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

这个程序有一个面板的对象数组,每当我放入一个新的面板时,这个数组就会增长。当它达到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

提前感谢!

编辑@Steve 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.Controls.Add(currentPanel);

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

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

我使用数组是因为历史记录显示最新的数组在顶部。为了做到这一点,每次我都必须将所有面板下移80px。

C#对象数组=null,不';t释放内存

因为将某个东西设置为null不会处理它,它只是取消引用它-垃圾收集器不会监视你的分配来检查你的null引用,而是在它想要的时候(其他都相等(或明确要求这样做时进行。

简而言之,因为null和内存管理是不同的东西。

除了Grant Thomas所说的,为什么不使用更容易管理的List<Panel>呢?

代码如下所示(假设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