Tencent / rapidjson

A fast JSON parser/generator for C++ with both SAX/DOM style API
http://rapidjson.org/
Other
14k stars 3.5k forks source link

Reserve存在重大内存泄漏 #2280

Open lxb320124 opened 1 month ago

lxb320124 commented 1 month ago

先写个小例子: for (int i = 0; i < 10000; i++) {
std::string value = "hello " + std::to_string(rand());
std::string key = "/data/a/b/c/" + std::to_string(i) + "/testValue"; Pointer(key).Set(doc, value); } 当使用这段代码测试时,内存会直接增长800多M,如果记录数更多的话,内存增长更加可怕 。 排查原因: ValueType& Pointer::Create 函数里面: if (v->IsArray()) { if (t->index >= v->Size()) { v->Reserve(t->index + 1, allocator); while (t->index >= v->Size()) v->PushBack(ValueType().Move(), allocator); exist = false; } v = &((v)[t->index]); } 因为上面每次增长一条记录,导致这里 v->Reserve 一直在执行,内存暴增。 if (v->IsArray()) { if (t->index == v->Size()) { v->PushBack(ValueType().Move(), allocator); exist = false; } else if (t->index > v->Size()) { v->Reserve(t->index + 1, allocator); while (t->index >= v->Size()) v->PushBack(ValueType().Move(), allocator); exist = false; } v = &((v)[t->index]); } 这里把代码修改一下,当 t->index == v->Size() 时,不使用Reserve,直接追加一条数据。 这样修改后,上面的示例内存大概只有30M左右,就正常了。

这里只是回避了 Reserve 内存泄漏的问题,具体如果修改这个函数,需要进一步研究。