0

I wrote this class that gets the exif data from video files, the code works fine, but if I loop through large amount of video files I run out of memory.

It doesn't seems like it release the reference to the shell file, i've tried to set it to null without luck

How do I release the memory? Thanks

class Program
{
    static void Main(string[] args)
    {

        List<vFile> VideoFileList = new List<vFile>();
        foreach (string filepath in Directory.GetFiles(@"D:\VIDEO", "*.*", SearchOption.AllDirectories))
            VideoFileList.Add(new vFile(filepath));
        Console.WriteLine("Ended");
        Console.ReadKey();//Prevent Close
    }
}
class vFile
{
    //File
    public string FileName { get; set; }
    public string FileType { get; set; }
    public string FilePath { get; set; }
    public double FileSize { get; set; }
    public DateTime MediaCreated { get; set; }

    //Shell
    public string[] Artist { get; set; }
    public string[] Keywords { get; set; }
    public ulong Duration { get; set; }
    public int FrameHeight { get; set; }
    public int FrameWidth { get; set; }
    public int Rating { get; set; }
    public string Publisher { get; set; }

    public vFile(string filepath)
    {
        //File
        FileName = Path.GetFileNameWithoutExtension(filepath);
        FileType = Path.GetExtension(filepath).Replace(".", "");
        FilePath = Path.GetFullPath(filepath);
        FileSize = new System.IO.FileInfo(filepath).Length;
        MediaCreated = File.GetCreationTime(filepath);

        //Shell
        using (ShellFile shellFile = ShellFile.FromFilePath(filepath))
        {
            if (shellFile.Properties.System.Music.Artist.Value != null)
                Artist = shellFile.Properties.System.Music.Artist.Value;
            if (shellFile.Properties.System.Keywords.Value != null)
                Keywords = shellFile.Properties.System.Keywords.Value;
            if (shellFile.Properties.System.Media.Duration.Value != null)
                Duration = shellFile.Properties.System.Media.Duration.Value.Value;
            if (shellFile.Properties.System.Video.FrameHeight.Value != null)
                FrameHeight = Int32.Parse(shellFile.Properties.System.Video.FrameHeight.Value.Value.ToString());
            if (shellFile.Properties.System.Video.FrameWidth.Value != null)
                FrameWidth = Int32.Parse(shellFile.Properties.System.Video.FrameWidth.Value.Value.ToString());
            if (shellFile.Properties.System.Rating.Value != null)
                Rating = Int32.Parse(shellFile.Properties.System.Rating.Value.Value.ToString());
            if (shellFile.Properties.System.Media.Publisher.Value != null)
                Publisher = shellFile.Properties.System.Media.Publisher.Value;
        }
    }
}
Drew Noakes
  • 300,895
  • 165
  • 679
  • 742
  • You could use a memory profiler to determine what kind of memory/objects are being leaked. – Drew Noakes Sep 19 '17 at 10:58
  • ShellFile is almost certainly a COM interop wrapper. That has consequences, the wrapper does not get cleaned-up and the native COM object doesn't get destroyed until the finalizer thread gets around to it. Which might take a while if the GC does not run often enough. Getting OOM is however pretty strange, the COM object isn't that big. I'll guess that this is just an approximation of the real code and the actual issue is that the finalizer thread is deadlocked. – Hans Passant Sep 19 '17 at 13:20

0 Answers0