【问题标题】:RAM consumption inside a C++ program using Sqlite3 blob使用 Sqlite3 blob 的 C++ 程序中的 RAM 消耗
【发布时间】:2016-02-25 00:00:25
【问题描述】:

我在 C++ 程序中使用 sqlite3 dbms,主要用于将文件存储为 blob 对象(我知道这不是最佳选择)。

显然我是增量写入它们的,因为它们有时会很大(40-80MB),为此我必须首先使用绑定函数sqlite3_bind_zeroblob(...) 创建 blob 的占位符,然后打开 blob 写入和渐进式地读取它。

我面临的问题是,当我创建 blob 占位符时(在sqlite3_step 期间),我的应用程序的 RAM 消耗在 2-3 秒内达到 80-160MB,一旦创建,RAM 消耗又回到最多 2-3MB。

我不明白为什么!如果他们创建了一种增量写入 blob 的方法,那么肯定有一种方法可以在不浪费 160MB RAM 的情况下创建那个愚蠢的占位符,但我没有找到它。你有什么建议吗?

sqlite3_stmt* stm = NULL;
sqlite3_blob *BLOB = NULL;

rc = sqlite3_prepare_v2(db, sql.c_str(), -1, &stm, NULL);

rc = sqlite3_bind_blob(stm, 1, wpath.c_str(), wpath.size()*sizeof(wchar_t), SQLITE_STATIC);
rc = sqlite3_bind_text(stm, 2, hash.c_str(), hash.size(), SQLITE_STATIC);
rc = sqlite3_bind_zeroblob(stm, 3, size);
rc = sqlite3_bind_int(stm, 4, versione);
rc = sqlite3_bind_blob(stm, 5, last.c_str(), last.size()*sizeof(wchar_t), SQLITE_STATIC);

rc = sqlite3_step(stm);

if (rc != SQLITE_DONE) {
    fprintf(stderr, " This file was already present in the database!\n", rc);
    return;
}
else {
    fprintf(stdout, "Record FILE created successfully\n");
}

【问题讨论】:

  • 这可能是零写入的缓存使用,尝试将缓存大小设置为最小?
  • 什么是 SQL 查询?
  • 我修改了缓存值,但似乎没有任何改变。无论如何,sql查询是以下 std::string sql = "INSERT INTO FILES (PATH , HASH , DATI , VER, LAST) VALUES (?1, ?2, ?3, ?4,?5);";跨度>
  • 您应该使用sqlite3_blob_open 和朋友来从增量 I/O 中受益。我在你的代码中没有看到。
  • 我在问题中写的,首先我需要创建占位符(第3个参数)然后我打开它并使用增量I / O写入,问题是占位符的创建浪费了很多内存。从文档-->“ Zeroblob 旨在用作 BLOB 的占位符,其内容是稍后使用增量 BLOB I/O 例程编写的。zeroblob 的负值会导致长度为零的 BLOB。” Myabe 你被第 5 个参数的绑定弄糊涂了。

标签: c++ sqlite blob


【解决方案1】:

这是HERE报告的问题。
而官方的回答是:

为了让 zeroblob 像上面一样工作(使用固定数量的 内存,不管它们有多大)所有的 zeroblob 都必须在最后 行的。换句话说,表的列是 接收 zeroblob 必须是表中的最后一列。如果 任何非零内容都跟在 zeroblob 之后,则 zeroblob 是 扩展为零字节的文字序列,这意味着内存必须 分配给整个 zeroblob。

所以你需要更改顺序来修复它:

sqlite3_stmt* stm = NULL;
sqlite3_blob *BLOB = NULL;

rc = sqlite3_prepare_v2(db, sql.c_str(), -1, &stm, NULL);

rc = sqlite3_bind_blob(stm, 1, wpath.c_str(), wpath.size()*sizeof(wchar_t), SQLITE_STATIC);
rc = sqlite3_bind_text(stm, 2, hash.c_str(), hash.size(), SQLITE_STATIC);
rc = sqlite3_bind_int(stm, 3, versione);
rc = sqlite3_bind_blob(stm, 4, last.c_str(), last.size()*sizeof(wchar_t), SQLITE_STATIC);
rc = sqlite3_bind_zeroblob(stm, 5, size);

rc = sqlite3_step(stm);

if (rc != SQLITE_DONE) {
    fprintf(stderr, " This file was already present in the database!\n", rc);
    return;
}
else {
    fprintf(stdout, "Record FILE created successfully\n");
}

【讨论】:

  • 非常感谢,我知道有对这种行为的解释和可能的解决方法!
猜你喜欢
  • 1970-01-01
  • 2018-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-11
  • 1970-01-01
  • 2015-11-22
相关资源
最近更新 更多