Я пытался использовать kyotocabinet TreeDB (сборка MSVC10) и наткнулся на странную проблему с памятью: в основном, при каждой записи в базу данных, использование памяти растет, и оно не падает, пока база данных не будет закрыта.
Тестовый код выглядит так:
size_t BLOCK_SIZE = 1 << 20; // use 1MB-sized records
char* test_block = new char[BLOCK_SIZE]; // allocate record data
TreeDB db;
db.open("test.db")
// add 5000 records
for (int i = 0; i < 5000; ++i)
{
// at each call, process virtual memory usage increases by 1 MB even though i'm not allocating more memory
// also, as expected, in x86-32 process the whole thing runs out of memory and crashes when iteration counter comes close to 2000
db.set(&i, sizeof(i), test_block, BLOCK_SIZE);
}
db.close(); // memory usage returns to normal here
delete [] test_block;
Конечно, я мог бы открывать / закрывать базу данных при добавлении каждой записи, но это приводит к огромной задержке (около 1 секунды), что неприемлемо для моей задачи.
Кроме того, эта проблема не возникает в HashDB, но я не могу использовать HashDB, так как мне иногда требуется последовательный доступ по ключу.
Я пытался изменить параметры настройки (tune_page_cache, tune_buckets, tune_page), но безуспешно. Не мог бы кто-нибудь намекнуть на то, что мне здесь не хватает? Мне нужно хранить непредсказуемое количество записей размером 100 КБ-10 МБ и запускать его в 32-разрядной системе.
возможно db.synchronize()
поможет, так как он должен вытолкнуть кэшированные данные в файловую систему, что позволит освободить память пользователя. Если это так, и вам нужно, чтобы это происходило постоянно, звоните open
с необязательным аргументом OAUTOSYNC, хотя это, скорее всего, сильно замедлит вас.
Других решений пока нет …