如何释放协议缓冲区内存

时间:2018-05-18 15:10:15

标签: c++ memory memory-leaks protocol-buffers

message LongUserIdSeqIdMapData {
map<int64, int32> userid_seqid = 1;
map<int32, int64> sedid_userid = 2; }

void GetUserIdSeqId(const std::string &user_id_seq_id_file) {
std::ifstream infile(user_id_seq_id_file);
infile.seekg(0, infile.end);
size_t length = infile.tellg();
infile.seekg(0, infile.beg);
auto *buffer = new char[length];
infile.read(buffer, length);
auto long_user_id_seq_id_map = new com::jaymz::poseidon::LongUserIdSeqIdMapData::LongUserIdSeqIdMapData();
if (!(*long_user_id_seq_id_map).ParseFromArray(buffer, length)) {
    std::cout << "Parse user_id_seq_id_file Fail, Please Check Your File!" << std::endl;
} else {
    std::cout << "Parse user_id_seq_id_file Success" << std::endl;
}
delete[] buffer;
delete long_user_id_seq_id_map;

}

我首先将LongUserIdSeqIdMapData数据写入文件,然后通过调用函数GetUserIdSeqId从文件中解析它,我发现程序在执行GetUserIdSeqId时占用190M物理内存,但在完成执行GetUserIdSeqId之后,程序仍然将190M物理内存作为no记忆被释放,我不知道为什么。

2 个答案:

答案 0 :(得分:0)

C / C ++内存分配函数不会将释放的内存返回给操作系统,但将其保存在自己的列表中以满足将来的分配,这是很常见的。

例如,如果使用new分配190 MB阵列,然后使用delete,那么操作系统工具很可能仍会显示该程序已使用190 MB。但是,要查看该函数是否真的泄漏了内存,可以运行两次。如果它泄漏内存,在第二次使用后它将需要380 MB - 但如果它已释放内存,它将重用相同的190 MB。

此行为通常可在C ++运行时中配置。但是已经选择了默认值,以便它们最适合常见用例。

答案 1 :(得分:0)

有一个在C ++中释放内存的函数:

google::protobuf::ShutdownProtobufLibrary();

https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.common#ShutdownProtobufLibrary.details

  

关闭整个协议缓冲区库,删除所有   由库分配或由生成的静态持续时间对象   .pb.cc文件。

     

您可能想要称之为两个原因:

     
      
  • 你使用了一个严格的“内存泄漏”定义,你希望每个malloc()都有一个相应的free(),即使是   在程序退出之前一直存在的对象。
  •   
  • 您正在编写一个动态加载的库,需要在卸载库时自行清理。
  •   
     

多次调用是安全的。但是,使用起来并不安全   协议的任何其他部分缓冲库之后   ShutdownProtobufLibrary()已被调用。

这可以解决你的问题!