Освобождение неуправляемого кода в C # - PullRequest
1 голос
/ 27 сентября 2010

Я вызываю часть неуправляемого кода C ++ из моего приложения C # рассчитать быстрое преобразование Фурье сигнала с дискретным временем.

Я звоню примерно так

IntPtr ptr = ComputeFFTW(packetSig, packetSig.Length, (int)samplFrequency,(int)fftPoints);

    unsafe
     {
           double *dPtr = (double*)ptr;

           for(int l = 0; l < fftData.Length; l++)
        {
          fftData[l] = dPtr[l];
            }   

      }

Хотя этот фрагмент кода работает нормально и дает мне желаемые результаты, я вижу, что во время вычисления происходит своего рода снижение производительности (утечка памяти). CLR не может вернуть локальные (двойные) переменные, и мое приложение значительно сожирает объем оперативной памяти.

Может кто-нибудь из вас подсказать, где я мог бы сделать это неправильно.

Со своей стороны, я запустил свое приложение, используя ANTS Mem Profiler, и я могу видеть на снимке, что двойные объекты требуют почти 150 МБ пространства памяти. Это нормальное поведение ??

Class Name  Live Size (bytes)   Live Instances
Double[]    150,994,980         3

В этом отношении приветствуется любая помощь. Шриватс

Ответы [ 2 ]

4 голосов
/ 27 сентября 2010

Поскольку функция C ++ выделяет память, вам придется вручную освободить этот кусок в приложении C # (освободить указатель). Лучший способ вызвать неуправляемый код - это выделить все переменные и фрагменты памяти (также и параметры Temp) в приложении C # и передать их в код C ++ в качестве параметров. Таким образом, у вас не будет проблем с памятью в неуправляемом коде.

0 голосов
/ 27 сентября 2010

Вы можете использовать метод Marshal.Copy (IntPtr, Double [], Int32, Int32) для копирования массива двойных значений из неуправляемого ptr в управляемый массив ffData.

IntPtr ptr = ComputeFFTW(packetSig, packetSig.Length, (int)samplFrequency,(int)fftPoints); 

Marshal.Copy(ptr, fftData, 0, fftData.Length);

Если ComputeFFTW возвращает указатель на динамически выделенную память, вам необходимо освободить его после использования. Сделайте это в неуправляемом коде, добавьте функцию типа Release и передайте ей ptr.

...