我的应用程序中存在大量内存泄漏。
这是在内存中加载大量内容的表单,它是一个包含3 FlowLayoutPanel
的表单。每个面板都有很多我创建的UserControl
,它们只是一个带标签的图片框。我们称之为ColorViewer
:
每当我打开此表单时,它需要接近300-400 MB的内存,而且似乎不会释放它。
正如你可以在我第一次打开ColorViewer
时,它会将所有内容加载到内存中(接近400mb),然后它就永远不会被丢弃。之后,每次打开ColorViewer
时都会正确处理。
这是我用来加载表单的代码,我猜内存泄漏是在img的加载中。截至目前,我使用默认的Dispose()
:
//Loading of one of the three panel in the form,called 3 time when the form is opened:
colorsViewerPanel.AddColorRange(colours.ConvertAll(x => new ColorBox(x.path_img, x.id,true)));
//Function that loads my UserControl into the panel
public void AddColorRange(List<ColorBox> cBoxList)
{
flowLayoutPanel1.SuspendLayout();
foreach (var cBox in cBoxList)
flowLayoutPanel1.Controls.Add(cBox);
flowLayoutPanel1.ResumeLayout();
}
//This is the ColorBox usercontrol's class
public string pathImg{ get; set; }
public int id{ get; set; }
public bool selected{ get; set; }
//This is the constructor for the UserControl
public ColorBox(string pathImage,int idImage,bool sel = true)
{
InitializeComponent();
pathImg = pathImage;
id = idImage;
selected = sel;
//Load img
if (File.Exists(pathImg))
{
Image img;
using (var bmpTemp = new Bitmap(pathImg))
{
img = new Bitmap(pathImg);
}
panelColor.BackgroundImage = img;
panelColor.BackgroundImageLayout = ImageLayout.Stretch;
labelColor.Text = id;
}
}
这是正常的吗?
答案 0 :(得分:0)
我认为您没有在这里布置任何有用的东西:
Image img;
using (var bmpTemp = new Bitmap(pathImg))
{
img = new Bitmap(pathImg);
}
您只是创建Bitmap类的实例(bmpTemp)(稍后将由于using语句而被丢弃),然后将同一类的新等距分配给另一个变量(img,即您正在使用的有效使用)。无论如何,即使您对此进行了纠正,也无法满足您的目的,因为将您实际显示的图像放置在PictureBox中没有任何意义(这也将在以后导致异常)。
如您在此处阅读的说明,有必要在Image对象上调用Dispose以有效消除其在内存中的存在,请注意,位图是非托管GDI +位图的包装(甚至可能需要特殊处理才能解决)
也就是说,给定您提供的代码并从根本上解决了问题,我想我可能会在ColorBox控件上实现IDisposable接口,以确保在控件处于打开状态时始终调用Image实例的Dispose方法。处置:
Implement IDisposable correctly
在您的特定情况下,我会将Image / Bitmap对象视为完全不受管理的对象,并且会在Dispose方法的“如果有的话,释放本地资源”部分中释放它,以便在有人使用您的如果没有控制该对象,则只要该对象符合终结条件,则无论如何都会调用终结器。像这样:
// The bulk of the clean-up code is implemented in Dispose(bool)
protected virtual void Dispose(bool disposing)
{
if (isDisposed) return;
if (disposing)
{
// free managed resources
managedResource.Dispose();
}
// free native resources if there are any.
if (!(img is null))
{
// Our Image.
img.Dispose();
}
isDisposed = true;
}