基本的单一生产者,单一消费者队列。内存未释放

时间:2019-03-19 13:50:44

标签: c++ c++14

我想实现一个基本的单一生产者,单一消费者WorkerQueue。问题在于,排队对象的内存没有被释放。

如果我

  1. 用1000个1MB大小的对象填充WorkerQueue :: queue_
  2. 致电WorkerQueue :: Start()

应用程序的内存使用量从1GB逐渐减少到零。

如果我

  1. 致电WorkerQueue :: Start();
  2. 用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);
}

0 个答案:

没有答案