утечка памяти при вызове неуправляемого кода из управляемого кода в Windows 7

StackOverflow https://stackoverflow.com/questions/1505489

Вопрос

Когда я вызываю неуправляемый код C ++ из своего кода C #, кажется, у меня какая-то утечка памяти.
C ++ считывает данные из файла, используя ifstream.read, и записывает их в вектор.

Это происходит только после обновления до Windows 7, в Vista этого не происходит, но если я использую версию собственной библиотеки dll, которая была скомпилирована в Vista, это ничего не меняет!
Если я запускаю тот же код на C ++ напрямую, без управляемого взаимодействия, утечки памяти не происходит!
Если я запускаю управляемый процесс, но внутри процесса vshost утечки памяти нет!

Вот подпись к звонку:

        [DllImport(DllPath, CharSet = CharSet.Unicode)]
    [return: MarshalAs(UnmanagedType.I1)]
    public static extern bool MyMethod(
        int x, 
        string  y, 
        string  z, 
        bool    v, 
        bool    w);

и тот , родной:

MyDll_Export bool APIENTRY MyMethod(
int x,
const wchar_t*  y, 
const wchar_t*  z,
bool v,
bool w)

Когда я вызываю это из C ++, я называю это следующим образом:

MyMethod(1, L"My String 1", L"My String 2", true, true)

Когда я смотрю на счетчики производительности для управляемой и неуправляемой памяти, я вижу, что вся память поступает из неуправляемого кода.
Учитывая, что маршалинг довольно прост, я не понимаю, в чем разница между вызовом C ++ напрямую или через C #.
Я также не знаю, почему это произошло только в Windows 7 (обе установки Windows имели .net 3.5 SP1).

У кого-нибудь есть идея, в чем причина этого?

Также, если кто-нибудь знает о встроенном инструменте профилирования памяти, который работает в Windows 7, я был бы рад узнать (на данный момент я только что напечатал для консоли все явные выделения памяти, и различий нет).

Это было полезно?

Решение

Я уверен, что проблема связана с маршалингом типов данных C # в соответствии с их частями счетчика C ++.Поскольку вы преобразуете возвращаемое значение bool в подписанное значение в 1 байт, может быть, вам следует сделать то же самое с аргументами функции?Тип C # bool равен 4 байтам, может быть, у вас там утечка?

Кроме того, может помочь указание неуправляемого типа для строк.

[DllImport(DllPath, CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.I1)]
public static extern bool MyMethod(
        int x,
        [MarshalAs(UnmanagedType.LPWStr)]
        [In] string y,
        [MarshalAs(UnmanagedType.LPWStr)]
        [In] string z,
        [MarshalAs(UnmanagedType.I1)]
        bool v,
        [MarshalAs(UnmanagedType.I1)]
        bool w);

Объяснение для комментатора:

Для типа C ++ bool:

В общем случае, ноль или нулевой указатель значение преобразуется в false, любое другое значение преобразуется в true.

...

Стандартная библиотека C ++ 1998 года определяет специализацию вектора шаблон для bool.Описание класс указывает, что реализация должна упаковывать элементы таким образом, чтобы каждый bool использовал только один бит памяти.

Таким образом, практически независимо от того, какое значение вы используете, вы получите логическое значение c ++ со значением true или false.

Другие советы

К сожалению, как только вы подключаете строки, никакая сортировка не является простой.

Нам понадобится еще немного данных, чтобы помочь вам отследить эту проблему.Можете ли вы предоставить следующее

  • Сигнатура собственного метода
  • Как управляется память для строк в машинном коде?
  • Возможно, пример C ++, где вы используете API?

Редактировать

Попробуйте использовать следующую подпись.Это говорит CLR не маршалировать память в обоих направлениях, а вместо этого только передавать данные в.

    [DllImport(DllPath, CharSet = CharSet.Unicode)]
    [return: MarshalAs(UnmanagedType.I1)]
    public static extern bool MyMethod(
            int x, 
            [In] string  y, 
            [In] string  z, 
            bool    v, 
            bool    w);

Я нашел применение тому, Профилировщик CLR полезно при обнаружении моей утечки памяти.

Вы уверены, что произошла утечка памяти?

Какова ваша основа для определения утечки памяти.Вы говорите, что можете видеть это по счетчикам производительности, но что вы наблюдаете на самом деле?Видите ли вы плавно поднимающуюся кривую или ту, которая останавливается на высоком уровне?Высокое потребление памяти часто путают с утечкой памяти.

кстати.Можете ли вы также опубликовать свое определение функции C ++?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top