我有一个winform应用程序。主要形式是单身,它加载了很多图像。图像代表产品,每次点击图像,我都会修改产品库存并重新加载产品和图像的哈希表。
问题在于我每次从BBDD重新加载产品的哈希表并重新加载图像。在一天结束时,应用程序耗尽了大量内存,我不知道何时以及如何卸载图像以便重新加载(因为有时我可以修改图像,我也必须重新加载)
重新加载哈希表和按钮的代码是:
Family fam = new Family();
List<Family> listFamilies = fam.loadFamilies();
htProducts.Clear();
foreach(Family family in listFamilies)
{
//reload all the products of each family
if(htProducts[family.idFamily]==null)
{
List<Product> listProducts= fam.loadProductsFamily(family.idFamily);
htProducts[family.idFamily] = listProducts;
}
Button bt = new Button();
bt.location = new Point(x,y); //The buttons are created dinamically
bt.Parent = panelFamilies;//I have all the buttons inside a panel.
try
{
if(family.urlImage !="")
{
bt.Text=family.Name;
bt.Image = new Bitmap(family.urlImage);
}
}
catch(Exception ex)
{
....
}
}
当我点击“家庭”按钮时,它会加载该系列的产品,但代码或多或少相同。它也会加载图像。
更多的是,这是代码。问题是每次我点击一个按钮,我会在产品上加载更多按钮并加载图片。
很多时候我重新加载单例表单并执行前面的代码,再次加载图像并耗尽内存。
¿何时以及如何卸载图像?
编辑:
我在再次加载带图像的按钮之前添加了以下代码:
foreach (Control c in panel8.Controls)
{
if (c is Button)
c.Dispose();
}
GC.Collect(GC.MaxGeneration);// I think that isn't correct to use because I've read, but reduces the memory.
它会处理面板的所有按钮和图像,并在再次加载图像之前减少内存?
对不起我的英文:(
非常感谢。
答案 0 :(得分:2)
foreach (Control c in panel8.Controls)
{
if (c is Button)
c.Dispose();
}
那不行。通常,当您在循环集合的foreach语句中更改集合时,.NET集合类会引发InvalidOperationException。不幸的是,这没有为Controls集合实现。所以这段代码所做的只是处理所有其他控件。这足以导致不受控制的资源泄漏,不仅仅是Button控件,还有他们的图像。
修复是向后迭代Controls集合,如下所示:
for (int ix = panel8.Controls.Count - 1; ix >= 0; --ix) {
Control c = panel8.Controls[ix];
// etc...
}
答案 1 :(得分:1)
听起来你在表格中持有一两个参考。
您应该使用像CLRProfiler或ANT这样的调试器来查看您的过程,以了解在您的过程中占用如此多内存的内容。获得此信息后,您可以采取下一步措施,确保释放所有引用信息,以便收集信息。
答案 2 :(得分:1)
要进行问题排查,请致电
GC.Collect(GC.MaxGeneration);
这将强制垃圾收集。然后在进程资源管理器或任务管理器中检查内存使用情况。如果它更小,它只意味着运行时决定不收集内存。
如果它不起作用,则需要找到内存泄漏。