c++ - 基本单生产者,单消费者队列。内存未释放
问题描述
我想实现一个基本的单一生产者,单一消费者 WorkerQueue。问题是,排队对象的内存没有被释放。
如果我
- 用 1000 个 1MB 大小的对象填充 WorkerQueue::queue_
- 调用 WorkerQueue::Start()
应用程序的内存使用量从 1GB 慢慢下降到零。
如果我
- 调用 WorkerQueue::Start();
- 用 1000 个 1MB 大小的对象填充 WorkerQueue::queue_
应用程序的内存使用量保持在 1GB 不变,直到程序退出。
在这两种情况下,所有数据包都被处理,并且数据包析构函数被调用 1000 次。因此,尽管 Packet 调用了析构函数,但内存似乎并没有被释放。当然,我希望能够在调用 ::Start() 后将项目排入队列。
平台:Ubuntu 18.10,g++-8
g++ -pthread -g -std=gnu++14 -o mytest main.cpp
#include <iostream>
#include <condition_variable>
#include <thread>
#include <vector>
#include <mutex>
using namespace std;
struct Packet {
explicit Packet(size_t size) {
data_.resize(size );
}
virtual ~Packet() {
data_ = std::vector<char>();
std::cout << "~Packet();\n";
}
std::vector<char> data_;
};
template<class T>
struct WorkerQueue {
void Start() {
t_ = std::move(thread{&WorkerQueue::Run, this});
}
void Enqueue(T t) {
std::lock_guard<std::mutex> l{m_};
queue_.push_back(std::move(t));
cv_.notify_one();
}
void Run() {
while(true) {
{
std::unique_lock<std::mutex> l{m_};
cv_.wait(l, [&](){return !queue_.empty();});
// calls T::~T()
queue_.erase(begin(queue_));
std::cout << "q_size: " << queue_.size() << endl;
}
// simulate workload
this_thread::sleep_for(50ms);
}
}
std::vector<T> queue_;
thread t_;
mutex m_;
condition_variable cv_;
};
int main() {
const size_t kPacketSize = 1*1000*1000;
WorkerQueue<std::unique_ptr<Packet>> wq;
wq.Start();// DOES NOT free memory
for(int i=0;i<1000;++i) {
wq.Enqueue(make_unique<Packet>(kPacketSize));
}
// wq.Start();// DOES free memory
this_thread::sleep_for(60s);
}
解决方案
推荐阅读
- python - 为什么 ImportContactsRequest (telethon 1.3) 方法不添加联系人也不产生错误?
- c++ - CRTP 中的复制赋值运算符 - gcc vs clang 和 msvc
- generics - 如果我有消息类型列表,如何在 MassTransit 中注册通用消费者适配器
- javascript - 谷歌地图 API JS 上的 3D 地球地球仪
- javascript - Mongoose:.find() 不返回任何文档
- flutter - 如何从单独的文件中使用颤振 url_launcher 函数?
- javascript - 如何在 vscode 中使用正则表达式替换或添加字符串?
- c# - 本地数据库 Visual Studio 2017 的连接问题
- symfony - 如何以 symfony 形式删除默认 ID 和名称?
- java - 双向单机不更新外键