У меня есть фрагмент кода JNI с утечкой памяти:
Detected memory leaks!
Dumping objects ->
{76} normal block at 0x277522F8, 52 bytes long.
Data: < "u' "u' "u' > F8 22 75 27 F8 22 75 27 F8 22 75 27 CD CD CD CD
Object dump complete.
Итак, я установил точку останова на указанном номере выделения памяти (в данном случае 76).
_crtBreakAlloc = 76;
Но приложение никогда не останавливает выполнение, как если бы это распределение никогда не выполнялось.
Я также сделал два снимка памяти в начале и в конце программы и сравнил их.
(в начале кода):
_CrtMemCheckpoint( &s1 );
(в конце кода):
_CrtMemCheckpoint( &s2 );
_CrtMemState s3;
_CrtMemDifference( &s3, &s1, &s2);
_CrtMemDumpStatistics( &s3 );
Вот результат:
0 bytes in 0 Free Blocks.
0 bytes in 0 Normal Blocks.
0 bytes in 0 CRT Blocks.
0 bytes in 0 Ignore Blocks.
0 bytes in 0 Client Blocks.
Largest number used: 2839 bytes.
Total allocations: 101483 bytes.
Кажется, все в порядке.
Я не могу понять, что происходит. Это ложная положительная утечка памяти? Или это утечка памяти из JVM? Если так, есть ли способ обнаружить это?
Добавлено после того, как решение найдено:
Я изменил инициализацию статического map
, и проблема была решена.
В частности, я преобразовал приватный статический член из map
в map*
. Проблема в том, что когда вы инициализируете static, он должен быть инициализирован константой.
Вот как я изменил объявление статического члена:
static const map<wstring, enumValue>* mapParamNames;
Итак, мой initialize()
метод становится:
map<wstring, paramNames>* m = new map<wstring, paramNames>();
(*m)[L"detectCaptions"] = detectCaptions;
(*m)[L"insertEmptyParagraphsForBigInterlines"] = insertEmptyParagraphsForBigInterlines;
(*m)[L"fastMode"] = fastMode;
(*m)[L"predefinedTextLanguage"] = predefinedTextLanguage;
(*m)[L"detectFontSize"] = detectFontSize;
(*m)[L"saveCharacterRecognitionVariants"] = saveCharacterRecognitionVariants;
(*m)[L"detectBold"] = detectBold;
(*m)[L"saveWordRecognitionVariants"] = saveWordRecognitionVariants;
KernelParamsSetter::mapParamNames = m;
Наконец, я вставил delete
карты в деструктор класса:
delete KernelParamsSetter::mapParamNames;
Надеюсь, это кому-нибудь пригодится.