winforms ImageList内存问题

winforms ImageList内存问题,winforms,memory-management,imagelist,Winforms,Memory Management,Imagelist,我有一个图像列表,里面有,你猜对了,图像。 这些图像作为位图加载到数据集中的内存中。在我把它们载入图像列表之前,记忆的增长并不令人担忧。但当它们被添加到ImageList中时,内存使用率会急剧上升。 但最大的问题是当我必须重新加载图像列表时。我尝试对列表中的每个图像调用dispose,但内存没有释放。 这是我试图清理内存的代码: foreach (Image item in imageList.Images) { item.Dispose(

我有一个图像列表,里面有,你猜对了,图像。 这些图像作为位图加载到数据集中的内存中。在我把它们载入图像列表之前,记忆的增长并不令人担忧。但当它们被添加到ImageList中时,内存使用率会急剧上升。 但最大的问题是当我必须重新加载图像列表时。我尝试对列表中的每个图像调用dispose,但内存没有释放。 这是我试图清理内存的代码:

        foreach (Image item in imageList.Images)
        {
            item.Dispose();

        }
        imageList.Images.Clear();

        GC.Collect();

我做错了什么?

您的dispose代码不合适。迭代图像集合实际上会为每个图像创建一个新位图。然后立即再次处理。打电话就可以了

Collect也不能有任何效果,ImageList类是本机Windows组件的包装器。它将图像存储在本机内存中,而不是垃圾收集内存中


最后但并非最不重要的问题是:Windows内存管理器的工作方式与您想象的不一样。释放内存时,它不会收缩程序的虚拟内存大小。它只是将内存块标记为未使用,并将其添加到空闲块列表中。准备好以后再使用。只有在极少数情况下,当释放的内存恰好跨越整个保留内存页集时,它才能缩小虚拟内存大小。这不是一个真正的问题。它是虚拟的。

您的dispose代码不合适。迭代图像集合实际上会为每个图像创建一个新位图。然后立即再次处理。打电话就可以了

Collect也不能有任何效果,ImageList类是本机Windows组件的包装器。它将图像存储在本机内存中,而不是垃圾收集内存中


最后但并非最不重要的问题是:Windows内存管理器的工作方式与您想象的不一样。释放内存时,它不会收缩程序的虚拟内存大小。它只是将内存块标记为未使用,并将其添加到空闲块列表中。准备好以后再使用。只有在极少数情况下,当释放的内存恰好跨越整个保留内存页集时,它才能缩小虚拟内存大小。这不是一个真正的问题。它是虚拟的。

Dispose循环和GC.Colect调用是在绝望中尝试解决问题的,因为仅仅调用Clear并不能解决问题。问题是,当我第二次填充列表时,如果列表太大,就会出现内存不足异常。这就是为什么我说内存没有被释放。在将位图添加到ImageList之后,是否要处理它们?我想我已经在foreach循环中尝试过了。我正在将位图添加到ImageList,以便ImageList.Images为我提供我正在尝试处理的位图。不,您误解了。在将位图添加到ImageList之后,必须尽早处理这些位图。本机控件生成一个副本。以后无法处理位图,因为引用已丢失。如果位图非常大,则OOM的可能性总是很大,因为内存正在碎片化。Dispose循环和GC.Colect调用是在绝望中尝试解决问题的,因为只调用Clear无法解决问题。问题是,当我第二次填充列表时,如果列表太大,则会出现内存不足异常。这就是为什么我说内存没有被释放。在将位图添加到ImageList之后,是否要处理它们?我想我已经在foreach循环中尝试过了。我正在将位图添加到ImageList,以便ImageList.Images为我提供我正在尝试处理的位图。不,您误解了。在将位图添加到ImageList之后,必须尽早处理这些位图。本机控件生成一个副本。以后无法处理位图,因为引用已丢失。如果位图非常大,那么OOM的可能性总是很大,因为内存正在变得碎片化。