AForge, стекирование памяти

Я пытаюсь получить кадр с помощью библиотек C # и AForge:

...
using AForge.Video
using AForge.Video.DirectShow

namespace Example
{
     class Program
     {

      private static Bitmap mySnap = null;

      static void Main(string[] args)
      {
             snapByte();
      }

      private static void snapByte()
      {
                    int Counter = 0;
                    FilterInfoCollection videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
                    VideoCaptureDevice videoSource = new VideoCaptureDevice(videoDevices[0].MonikerString);
                    videoSource.NewFrame += new NewFrameEventHandler(videoNewFrame);
                    videoSource.Start();
                    do
                    {
                        Thread.Sleep(500);
                        Counter++;
                    }
                    while (mySnap == null && Counter < 4);
                    if (videoSource.IsRunning)
                    {
                        videoSource.SignalToStop();
                        videoSource.WaitForStop();
                        videoSource = null;
                    }
                    MemoryStream myStream = new MemoryStream();
                    mySnap.Save(myStream, ImageFormat.Png);
                    byte[] snapByteLength = MyStream.ToArray();
                    int snapLength = snapByteLength.Length;
                    Console.WriteLine(snapLength);
                    Console.ReadLine();
                    myStream.Dispose();
                    mySnap = null;
                    snapByte();
            }
        }

        private static void videoNewFrame(object sender, NewFrameEventArgs eventArgs)
        {
             mySnap = (Bitmap)eventArgs.Frame.Clone();
        }
   }
}

это точный код, который я использую, я просто изменил обработку байтов изображения, чтобы отобразить длину байта, чтобы упростить ситуацию.

проблема, с которой я сталкиваюсь, заключается в том, что память будет занимать где-то между 1-2 МБ каждый раз, когда делается снимок. Я избавляюсь от всех своих растровых изображений, кроме mySnap, который я возвращаю к нулю. он используется снова, и я должен объявить его глобальным, потому что я использую это в snapByte() и newVideoFrame(), но, поскольку я повторно использую mySnap, я не понимаю, почему он складывается... он должен перезаписываться каждый раз...

Я видел другие ответы, но все они связаны с окном изображения, и ответ состоит в том, чтобы очистить окно изображения перед загрузкой нового изображения. Я полагаю, что делаю здесь то же самое, снова вызывая mySnap=null.. но память все еще накапливается. ..

Спасибо..


person JoelContreras    schedule 04.06.2017    source источник
comment
никто?? Я предполагаю, что это должна быть утечка памяти в библиотеках AForge, тогда...   -  person JoelContreras    schedule 06.06.2017


Ответы (1)


Вы создаете бесконечную рекурсию своим безусловным вызовом snapByte() в конце метода snapByte(). Это создает цикл, который в конечном итоге выйдет из строя, когда в вашем стеке закончится место; каждый раз, когда ваш метод вызывает сам себя, вы настраиваете новый кадр стека, который никогда не будет очищен, потому что метод никогда не возвращается. Это может занять некоторое время, чтобы проявиться из-за вызова Thread.Sleep(), который будет ограничивать ваши рекурсивные вызовы.

Кроме того, любая ссылка, которая не была обнулена до того, как вы рекурсивно вызвали snapByte(), будет храниться в памяти неопределенное время, поскольку эти ссылки находятся в области действия, которая никогда не выйдет (из-за бесконечной рекурсии) и никогда не будет восстановлена ГК.

Это относится к вашей коллекции videoDevices, но, что более важно, к экземпляру массива snapByteLength, который содержит копию только что захваченного растрового изображения. Бьюсь об заклад, это основная причина утечки памяти.

Избегание рекурсии и преобразование ее в простой цикл должны решить ваши проблемы.

person BlueStrat    schedule 07.06.2017
comment
Спасибо большое..теперь вижу! вместо этого реализует цикл, спасибо. - person JoelContreras; 07.06.2017
comment
De nada Joel, da gusto encontrar por aquí gente de México =) - person BlueStrat; 07.06.2017