Утечка памяти JNA - PullRequest
       5

Утечка памяти JNA

7 голосов
/ 05 марта 2012

Учитывая этот код C ++:

void LoadData(char** myVar)
{
    std:: string str("[Really Long String Here]");
    unsigned int size = str.length() + 1;
    *myVar = new char[size];
    strncpy(*myVar, str.c_str(), size);
}

И этот JNA Java:

Pointer myVar = new Memory(Pointer.SIZE);
this.Lib.LoadData(myVar);
this.someVar = myVar.getPointer(0).getString(0);

У меня возникают утечки памяти, насколько я понимаю, getPointer (0) должен создатьобъект указателя, который должен быть освобожден при finalize (), но, похоже, его нет.

Я что-то упустил?Это похоже на спецификацию ... и я могу запустить вышеописанную функцию без утечек в C ++ нормально.

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

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

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

Не бери в голову, я даже не думаю, что есть способ сделать бесплатно вручную через JNA, не расширяя его ...

Ответы [ 3 ]

3 голосов
/ 06 марта 2012

Добавьте эту функцию в библиотеку C ++ ...

void FreeData(char** myVar)
{
    delete [] *myVar;
}

И затем сделайте этот код JNA

Pointer myVar = new Memory(Pointer.SIZE);
this.Lib.LoadData(myVar);
this.someVar = myVar.getPointer(0).getString(0);
this.Lib.FreeData(myVar);

Таким образом, вы выделите и удалите память в C ++.

1 голос
/ 05 марта 2012

Выделите в вызывающем абоненте, а не в вызываемом.

Например:

int LoadData(char* buf, int maxlen) {
    std:: string str("[Really Long String Here]");
    strncpy(buf, str.c_str(), maxlen);
    if (str.length() < maxlen) 
        return str.length();
    return maxlen;
}

Затем при вызове из Java передайте byte[] соответствующего размера. Обратите внимание, что эта реализация потенциально очень неэффективна, но идея в том, что вы обычно не хотите выделять память в одном контексте и освобождать ее в другом.

0 голосов
/ 05 марта 2012

Вместо myVar = новый символ [размер]

используйте

*myVar = malloc(size);
strncpy(*myVar, str.c_str(), size);

Массивы необходимо удалить как: delete [] * myVar;

JNAне знаю, как это сделать.

...