Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从jpgs程序中搜索Gif中的内存泄漏_C#_.net_Memory Leaks - Fatal编程技术网

C# 从jpgs程序中搜索Gif中的内存泄漏

C# 从jpgs程序中搜索Gif中的内存泄漏,c#,.net,memory-leaks,C#,.net,Memory Leaks,我编写了一个C#程序,它接受一个目录名,以100个为一批遍历其中的文件,并输出GIF class Program { static void Main(string[] args) { GifBitmapEncoder encoder = new GifBitmapEncoder(); int i = 0; int filei = 0; foreach (string fileName in Directory.G

我编写了一个C#程序,它接受一个目录名,以100个为一批遍历其中的文件,并输出GIF

class Program
{
    static void Main(string[] args)
    {
        GifBitmapEncoder encoder = new GifBitmapEncoder();

        int i = 0;
        int filei = 0;
        foreach (string fileName in Directory.GetFiles(args[0]).OrderBy(s => s))
        {
            i++;
            AddFileToBitmap(encoder, fileName);
            Console.WriteLine("Added file {0:000}: {1}", i, fileName);

            if (i % 100 == 0)
            {
                string outFile = string.Format("output{0}.gif", filei);
                Console.WriteLine("Saving to file: {0}", outFile);
                SaveGif(encoder, outFile);

                filei++;
                encoder.Frames.Clear();
                encoder = new GifBitmapEncoder();
                GC.Collect();
                Console.WriteLine();
            }
        }
    }

    static void AddFileToBitmap(GifBitmapEncoder encoder, string fileName)
    {
        using (Bitmap img = (Bitmap)Bitmap.FromFile(fileName))
        {
            BitmapSource bitmap = Imaging.CreateBitmapSourceFromHBitmap(
                img.GetHbitmap(),
                IntPtr.Zero,
                Int32Rect.Empty,
                BitmapSizeOptions.FromEmptyOptions());

            encoder.Frames.Add(BitmapFrame.Create(bitmap));
        }
    }

    static void SaveGif(GifBitmapEncoder encoder, string fileName)
    {
        using (FileStream stream = new FileStream(fileName, FileMode.Create))
        {
            encoder.Save(stream);
        }
    }
}
当我运行它时,内存使用从~1MB开始,在前100个图像中增长到~800MB;对于第二个100幅图像,下降到~400MB,并增长到~1.2GB;下降到约800MB,并因剩余30个图像的内存不足错误而崩溃

我想某处有内存泄漏,但我找不到
GifBitmapEncoder
BitmapSource
BitmapFrame
不可
IDisposable
,因此我无法处理其中的任何变量,也看不到我使用的任何其他变量。可能是
img.GetHbitmap()
返回
IntPtr

有什么想法吗

我从中获得了代码的主要部分。

试试这个:

        using (Bitmap img = (Bitmap)Bitmap.FromFile(fileName))
        {
            IntPtr hBitmap = img.GetHbitmap();

            BitmapSource bitmap = Imaging.CreateBitmapSourceFromHBitmap(
                hBitmap,
                IntPtr.Zero,
                Int32Rect.Empty,
                BitmapSizeOptions.FromEmptyOptions());

            encoder.Frames.Add(BitmapFrame.Create(bitmap));

            DeleteObject(hBitmap);
        }
文件:

您负责调用GDI DeleteObject方法来释放 GDI位图对象使用的内存。有关 GDI位图,请参阅Windows GDI文档中的位图

试试这个:

        using (Bitmap img = (Bitmap)Bitmap.FromFile(fileName))
        {
            IntPtr hBitmap = img.GetHbitmap();

            BitmapSource bitmap = Imaging.CreateBitmapSourceFromHBitmap(
                hBitmap,
                IntPtr.Zero,
                Int32Rect.Empty,
                BitmapSizeOptions.FromEmptyOptions());

            encoder.Frames.Add(BitmapFrame.Create(bitmap));

            DeleteObject(hBitmap);
        }
文件:

您负责调用GDI DeleteObject方法来释放 GDI位图对象使用的内存。有关 GDI位图,请参阅Windows GDI文档中的位图

试试这个:

encoder.Frames.Clear();
encoder = null;
GC.Collect();
//GifBitmapEncoder derives from DispatcherObject which has finalizer
GC.WaitForPendingFinalizers();
//then create a new instance
encoder = new GifBitmapEncoder();
试试这个:

encoder.Frames.Clear();
encoder = null;
GC.Collect();
//GifBitmapEncoder derives from DispatcherObject which has finalizer
GC.WaitForPendingFinalizers();
//then create a new instance
encoder = new GifBitmapEncoder();

如果你分析你的应用程序,你可以准确地看到被分配的内容——这将消除所有疑问,避免我们假装自己是编译器。如果你分析你的应用程序,你可以准确地看到被分配的内容——这将消除所有疑问,避免我们假装自己是编译器。奇怪的是,这似乎是Task Manager的解决方案,但我仍然在同一位置遇到了
OutOfMemory
异常,尽管只使用了167MB的RAM。我还注意到它似乎只在添加最后一帧后才这样做。由于我的代码中有一个错误,我甚至没有保存最后一个gif,所以它在试图退出程序时抛出了错误。更准确地说,它在退出文件名上的
foreach
循环时失败。我刚刚找到了答案。有一个名为thumbs.db的隐藏文件,我没有过滤掉。奇怪的是,这似乎是任务管理器的解决方案,但我仍然在同一个位置遇到了
OutOfMemory
异常,尽管只使用了167MB的RAM。我还注意到它似乎只在添加最后一帧后才这样做。由于我的代码中有一个错误,我甚至没有保存最后一个gif,所以它在试图退出程序时抛出了错误。更准确地说,它在退出文件名上的
foreach
循环时失败。我刚刚找到了答案。我没有过滤掉一个名为thumbs.db的隐藏文件。