【问题标题】:C++ bad memory alloc exceptionC++ 错误的内存分配异常
【发布时间】:2015-06-02 03:40:00
【问题描述】:

这是我正在尝试做的事情的要点。我将文件存储在 SQL 表中。该表很大,有 400 条记录,但每条记录都存储文件存档,每个记录的大小约为 100MB。最近,我们不得不更改我们的加密密钥。所以我正在编写一个线程(5 个线程)代码来使用旧密钥解密,然后使用新密钥进行加密。这是每个线程所做的

struct DataToReencrypt
{
     int id;
     string data;
}
vector<DataToReencrypt> results;

// database open
SELECT ID,FileData From Files WHERE ID BETWEEN 1 AND 80 // 81-160 and so on.
// database connection close

// database connection open
for(int i=0;i<results.size();i++ )  // results contain the result of the above query.
{
    string decrypted = LegacyDecryption(results[i].FileData);
    string encrypted = NewEncryption(decrypted);

    UPDATE Files SET FileData = encrypted WHERE ID = results[i].ID;
}
// database connection close

问题是当我尝试这样做时,我得到了这个 C++ bad_memory 分配异常和 SQL 内存分配异常。当我阅读 bad_memory 分配异常时,我读到 C++ 在编译器无法分配新内存时抛出它。以防万一,如果这有帮助,我在具有 6GB RAM 的系统上运行它(我必须使它在 6GB RAM 中工作,因为它是我们的产品支持的最低限度)并且当这个进程运行时 sqlserver.exe 进程几乎需要 4GB RAM 空间。请帮助解决此方法的任何问题或任何可以改进的问题。

【问题讨论】:

  • 我不确定这里有很多内容,您的内存不足。通常解决方案是使用更少的内存。
  • 要明确一点 - 每条记录是 100MB,而您正在将其中的 80 条读入内存?这不适合 6GB
  • @TheDark 你是对的。最大文件大小为 100MB。至少有一半的文件更少。但我不想为未来的证明做假设。此外,这在 2 或 3 次中正确运行一次。所以我认为这是内存问题。无论如何要改进这里的流程?
  • 我会说最好让每个线程一次读取一个项目并处理它。这样每个线程将使用最多 200MB 的内存(大约)。因此,只需将 select 语句放入循环中,一次只选择一项。如果 ID 不总是连续的,您仍然可以使用外部选择来获取 ID。
  • @TheDark 感谢您的建议。这种方法的问题是 ID 字段应该是连续的。一般情况下,如果ID不连续怎么修改呢?

标签: c++ sql multithreading performance exception


【解决方案1】:

@TheDark 在他最后的评论中给出了一个很好的建议。如果是我并且我知道表中的计数或者我可以检索数据计数,那么我将执行类似于以下的操作:

// database connection open
for(int i=0;i<80;i++ )  // ...160...240...etc for each thread
{
    string data;

    SELECT ID,FileData From Files WHERE ID = i // 81-160 and so on.

    // data = FileData from query

    string decrypted = LegacyDecryption(data);
    string encrypted = NewEncryption(decrypted);

    UPDATE Files SET FileData = encrypted WHERE ID = i;
}
// database connection close

这将减少到目前为止使用的内存量并摆脱结构。当然,这意味着您的 id 是连续的,但我认为它们是连续的,因为您正在为这种特定类型的数据使用表。

【讨论】:

  • 感谢您的建议。如果 ID 不连续,这将如何变化?
  • @Crusher:如果 id 不连续,那么我假设您正在使用不同的 WHERE 条件进行查询。我会在循环之外执行“SELECT ID WHERE X = Y”并将数据存储到没有 FILEDATA 的 vector ids 中(这应该在您所需的内存大小范围内,因为这只是一个整数向量)。然后使用vector.size() 调整for 循环和vector 内的数据以查询表WHERE ID = Vector.at(i)。希望这是有道理的......
猜你喜欢
  • 2015-01-09
  • 1970-01-01
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
  • 2013-05-13
  • 2023-04-06
  • 1970-01-01
  • 2019-09-28
相关资源
最近更新 更多