You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows Form图片浏览应用双向链表内存占用过高问题求助

Windows Form图片浏览器内存泄漏问题

我开发了一款Windows Form图片浏览应用,通过PictureBox显示图片,点击左右箭头可切换同文件夹中的上一张/下一张图片。为实现快速切换,我预加载了当前显示图片、5张前置图片和10张后置图片(共16张),并将这些图片存储在双向链表中。但切换图片时程序内存持续攀升,未释放不再使用的图片资源。我曾尝试在NextImage和PreviousImage方法末尾调用System.GC.Collect(),但无效果。

之后我采纳建议将自定义链表替换为C# LinkedList,同时添加了Bitmap.Dispose()调用,不过仍存在内存占用过高的问题。以下是管理图片缓存的ImageController类及辅助IndexObject类的代码:

public class ImageController
{
    private string imageFolder = "";

    // 存储文件夹中所有图片的路径
    private List<string> imageFiles;

    private LinkedList<Bitmap> imageLinkedList;
    private LinkedListNode<Bitmap> currentNode;

    // 支持的图片扩展名集合
    private HashSet<string> supportedExtensions = new HashSet<string>() { "bmp", "gif", "exif", "jpg", "png", "tiff" };

    // 当前图片在imageFiles中的索引
    private IndexObject currentIndex;

    // 最早加载的图片在imageFiles中的索引
    private IndexObject oldestIndex;

    // 最新加载的图片在imageFiles中的索引
    private IndexObject newestIndex;

    // 链表缓存的数量限制
    private int oldCache = 5;
    private int newCache = 10;

    // 返回当前显示的图片
    public Bitmap Image { get { return currentNode.Value; } }

    // 返回当前图片的路径
    public string ImagePath { get { return imageFiles[currentIndex.Index]; } }

    public ImageController(string fileName)
    {
        imageFolder = Path.GetDirectoryName(fileName);
        imageFiles = Directory.EnumerateFiles(imageFolder).ToList();
        imageFiles.RemoveAll(t => !supportedExtensions.Contains(Path.GetExtension(t).Replace(".", "").ToLower()));

        currentIndex    = new IndexObject(imageFiles.IndexOf(fileName), imageFiles.Count);
        oldestIndex     = new IndexObject(currentIndex.Index, imageFiles.Count);
        newestIndex     = new IndexObject(currentIndex.Index, imageFiles.Count);

        imageLinkedList = new LinkedList<Bitmap>();
        LoadCache();
    }

    private void LoadCache()
    {
        currentNode = imageLinkedList.AddFirst(new Bitmap(imageFiles[currentIndex.Index]));

        // 加载左侧缓存图片
        for (int i = 0; i < oldCache; i++)
        {
            oldestIndex.Index--;
            imageLinkedList.AddFirst(new Bitmap(imageFiles[oldestIndex.Index]));
        }

        // 加载右侧缓存图片
        for (int i = 0; i < newCache; i++)
        {
            newestIndex.Index++;
            imageLinkedList.AddLast(new Bitmap(imageFiles[newestIndex.Index]));
        }
    }
    public Bitmap NextImage()
    {
        currentIndex.Index++;
        oldestIndex.Index++;
        newestIndex.Index++;

        // 释放并移除最早的图片
        imageLinkedList.First.Value.Dispose();
        imageLinkedList.RemoveFirst();

        // 添加新的图片到链表末尾
        imageLinkedList.AddLast(new Bitmap(imageFiles[newestIndex.Index]));

        currentNode = currentNode.Next;

        return currentNode.Value;
    }
    public Bitmap PreviousImage()
    {
        currentIndex.Index--;
        oldestIndex.Index--;
        newestIndex.Index--;

        // 释放并移除最新的图片
        imageLinkedList.Last.Value.Dispose();
        imageLinkedList.RemoveLast();

        // 添加新的图片到链表头部
        imageLinkedList.AddFirst(new Bitmap(imageFiles[oldestIndex.Index]));

        currentNode = currentNode.Previous;

        return currentNode.Value;
    }

}

public class IndexObject
{
    private int _index;
    private int _limit;
    public IndexObject(int index, int limit)
    { 
        _index = index;
        _limit = limit;
    }
    public int Index
    {
        get
        {
            if (_index >= 0)
                return _index % _limit;
            else
                return _limit + _index;
        }
        set
        {
            if (value >= 0)
                _index = value % _limit;
            else
                _index = _limit + value;
        }
    }
}

内容的提问来源于stack exchange,提问作者Carlos Siestrup

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 11:59:55