【发布时间】:2013-01-08 09:00:22
【问题描述】:
在我做的项目中出现了内存泄漏。我重写了所有的函数来修复一些,但还剩下一个:
该程序有一个面板对象数组,每次我放入一个新面板时,它都会增长。当它达到 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;
}
为了修复滚动错误,我使用了一个 Panel HistoryPanel 我将 currentPanel 放在了其中:
HistoryPanel.Controls.Add(currentPanel);
然后我添加所有控件:用户名、当前时间和头像。
为了保存面板,我在创建空间后将其添加到阵列面板中,如上所示:panels[panels.Length-1] = currentPanel;
我使用数组是因为历史记录显示最新的数组。每次我必须将所有面板向下移动 80 像素时都要这样做。
【问题讨论】:
-
可以使用垃圾回收器来释放内存:
GC.GetTotalMemory(true) -
如果我没记错的话,你必须先在面板上调用 dispose。否则,它们将不会被释放。
-
如果我使用 de 垃圾收集器,我必须将它放在代码中的什么位置,并让我为数组创建析构函数或其他东西?
-
手动调用垃圾收集器不是个坏主意吗?垃圾收集器不应该检测可释放对象本身并在程序空闲时收集它吗?
-
AFAIK 垃圾收集器不应该永远被显式调用,除非你知道它需要被调用(处理非托管资源?)。仅供参考,如果您将
panels设为一个集合(即List<>),它将非常适合您的代码:panels.RemoveAt(0);,您就完成了。