Почему Нлохманн не освобождает память - PullRequest
0 голосов
/ 28 января 2020

Я использую библиотеку nlohmann для анализа JSON кодов. У нас есть две проблемы:
1- Почему nlohmann использует огромную память для разбора данных
2- После вызова синтаксического анализатора в функции локально, как показано ниже, код не освобождает память. Мой JSON размер данных составляет около 8 МБ, и синтаксический анализатор использует для анализа более 50 МБ . Я проанализировал эти JSON данные 10 раз, и использование памяти увеличилось до 600 МБ , и после завершения функции память не освободилась.

#include "nlohmann/json.hpp"

    #define REPEAT 10

        void GenerateNlohmann() {
          std::string filePath{FILE_ADDRESS};
          std::ifstream iFile(filePath.c_str(), std::ios::in);
          std::string data{};
          if (iFile.is_open()) {
            data = std::string((std::istreambuf_iterator<char>(iFile)),
                               std::istreambuf_iterator<char>()); // About 8MB size
            iFile.close();
          }
          if (!data.empty()) {
            nlohmann::json json = nlohmann::json::parse(data); // Use memory about 50MB
            std::vector<nlohmann::json> jsons{};
            for (int i = 0; i < REPEAT; ++i) {
              nlohmann::json j = nlohmann::json::parse(data);
              jsons.emplace_back(j);
            }
            while (!jsons.empty()) {
              jsons.pop_back();
            }
          }
        }

            int main() {
              GenerateNlohmann();

        // Now memory usage is about 600MB
              std::cout << "Input a numberto exit" << std::endl;
              int i;
              std::cin >> i;

              return 0;
            }

1 Ответ

0 голосов
/ 10 февраля 2020

Я успешно воспроизвел в Ubuntu. Мой json размер данных около 1,4 КБ, но я анализировал эти json данные много раз. Вот мой результат теста:

Перед запуском:

KiB Mem :  8167476 total,  5461204 free,   284120 used,  2422152 buff/cache

1000 times:
KiB Mem :  8167476 total,  5456600 free,   288724 used,  2422152 buff/cache

10000 times:
KiB Mem :  8167476 total,  5405916 free,   339376 used,  2422184 buff/cache

100000 times:
KiB Mem :  8167476 total,  4893176 free,   852104 used,  2422196 buff/cache

After input the int (After run)
KiB Mem :  8167476 total,  5462208 free,   283116 used,  2422152 buff/cache

Действительно, есть проблема, но это оптимизация с помощью распределителя (вероятно, glib c в моем случае) и не относится к библиотеке.

Если я добавлю malloc_trim (0) в моем коде:

while (!jsons.empty()) {
      jsons.pop_back();
    }

+   malloc_trim(0);
  }

Я найду, что все будет хорошо. В windows мы не можем воспроизвести, потому что мы используем не glib c, я думаю.

Другой тест: я написал другую программу для mallo c много маленькой памяти с glib c, и проблема останется живой. Моя программа не связана с библиотекой, она просто mallo c и освобождает много маленькой памяти .

В любом случае, проблема не связана с библиотекой. Если мы добавим в библиотеку malloc_trim (0) , во время синтаксического анализа будет много вызовов, что снизит производительность. Поэтому лучшее решение - добавить malloc_trim (0) в вашем коде.

...