Высокое потребление памяти благодаря умным указателям. Переполнение стека

Я запутался в использовании указателей / smartpointer в C ++.
Мы хотим захватить пакеты с сетевой карты. Мы используем PF_RING ZC для захвата пакетов следующим образом:

typedef folly::ProducerConsumerQueue<std::string> ZCTask;
typedef boost::shared_ptr<ZCTask> ZCTask_ptr;

void runZCConnection() {
ZCTask_ptr activeBufferConnection(new folly::ProducerConsumerQueue<std::string>(200000));
LOG_INFO("capture_loop for connections: Entering >> SHARE POINTER .");
int h = 0;
for (;;) {
if (likely(pfring_zc_recv_pkt(zqc, &buffer_connection, _wait_for_packet) >= 0)) {
u_char *pkt_data = pfring_zc_pkt_buff_data(buffer_connection, zqc);
std::string payload(pkt_data + _ConnectionHeaderSize, pkt_data + _snapLengthConnection);

if (activeBufferConnection->isFull()) {
LOG_INFO("ZC Active buffer Connction is full");
_buffersConnection.add(activeBufferConnection);
LOG_INFO(">> after add. USAGEG   %ld", activeBufferConnection.use_count());
activeBufferConnection.reset(new folly::ProducerConsumerQueue<std::string>(200000));
LOG_INFO(">> after reset. USAGEG   %ld", activeBufferConnection.use_count());
folly::ProducerConsumerQueue<std::string>(_bufferSizeConnection + 1);
if (h++ > 25) {
break;
}

}
activeBufferConnection->write(payload);
continue;
}
}

for (int a = 0; a < 25; a++) {
//get new task
Node* node = _buffersConnection.get2();
{
ZCTask_ptr zcTaskConnection = node->Data;
delete node;
node = NULL;
LOG_INFO(">> After node delete. USAGEG   %ld",
LOG_INFO("connection buffer : %d", a);

}
}
LOG_INFO("delete");
} //packet consumer

Как видно, в первую очередь мы храним пакеты на глупость SPMC очередь в runZCWrapper. Когда очередь заполнена, записывается в связанный список с именем _ buffersConnection.

Захват работает отлично, и мы сохраняем все пакеты. Наша проблема с этим спокойствием кода заключается в его высоком потреблении памяти. Когда прибывает упакованный, activeBufferConnection сохраняет его. Когда количество пакетов увеличивается до 1000000, создается новый activeBufferConnection, и последний сохраняется в связанном списке с именем buffersconnections. Мы устанавливаем количество соединений буфера до 25.

Как видно из приведенного выше кода, мы используем умные указатели для
Указывая на activeBufferConnection. когда activeBufferConnection заполнен, его указатель передается методу add для буферных соединений.

Вот некоторые коды нашего класса ArchiveList, который используется в runZCConnection;

class ArchiveList {
typedef folly::ProducerConsumerQueue<std::string> ZCTask;
typedef boost::shared_ptr<ZCTask> ZCTask_ptr;
private:
Node* root;Node* last;
std::mutex mutex_;
std::condition_variable cond_;
public:

ArchiveList() {
root = new Node();
last = root;
}

Node*
get2() {
std::unique_lock<std::mutex> mlock(mutex_);
while (root->Next == NULL) {
LOG_INFO("get null");
cond_.wait(mlock);
}
LOG_INFO("1");
Node* toDelete = root->Next;
LOG_INFO("1");
root->Next = toDelete->Next;
LOG_INFO("1");
return toDelete;
}

void
add(ZCTask_ptr item) {
std::unique_lock<std::mutex> mlock(mutex_);
Node* newItem = new Node();
newItem->Data = item;
newItem->Prev = last;
last->Next = newItem;
last = newItem;

mlock.unlock();
cond_.notify_one();
LOG_INFO("+");
}

};

Когда число activeBufferConnection увеличилось до 25, первый цикл завершился, и второй цикл начал работать. Второй цикл удаляет все 25 элементов связанного списка.
Вот некоторые коды нашего Node Class, который используется в runZCConnection;

class Node {
public:
typedef folly::ProducerConsumerQueue<std::string> ZCTask;
typedef boost::shared_ptr<ZCTask> ZCTask_ptr;

Node() {
Next = NULL;Prev = NULL;Data = NULL;
}

~Node() {
Next = NULL;Prev = NULL;
LOG_INFO(" >> NODE DCTOR. USAGEG   %ld", Data.use_count());
Data.reset();
LOG_INFO("NODE DCTOR");
}

ZCTask_ptr Data;
Node* Next;
Node* Prev;
private:
};

Выход из Топ Команда это проблема. первый цикл runZCConnection хранит пакеты в некоторых буферах. После удаления буферов в его цикле второстепенного использования используемая ими память не освобождается, и мы не знаем, почему это произошло.

                    CPU     MEM
83698 root         49.3    0.3      0:01.49 ng4-m2
83698 root         39.1    0.6     0:02.67 ng4-m2
83698 root         41.5    0.8     0:03.92 ng4-m2
83698 root         1.3     1.0     0:05.49 ng4-m2
83698 root         1.0     1.0      0:05.52 ng4-m2
83698 root         1.7     0.9     0:05.57 ng4-m2

Как показывает команда top, память не освобождается после того, как программа удалит все свои буферы. Проблема может быть связана с неправильным удалением буферов или может быть связана с неправильным использованием указателей. Мы устанавливаем некоторые журналы в некоторых местах кода, который возвращает некоторую информацию о программе и ее состоянии указателя.
Вот несколько строк вывода:

INFO    | ZCWrapper.hpp   | runZCConnection:260 : ZC Active buffer Connction is full
INFO    | ArchiveList.h   | add:80 : +
INFO    | ZCWrapper.hpp   | runZCConnection:262 : >> after add. USAGEG   2
INFO    | ZCWrapper.hpp   | runZCConnection:264 : >> after reset. USAGEG   1
.
.
.
INFO    | ArchiveList.h   | get2:56 : 1
INFO    | Node.hpp        | ~Node:27 :  >> NODE DCTOR. USAGEG   2
INFO    | Node.hpp        | ~Node:29 : NODE DCTOR
INFO    | ZCWrapper.hpp   | runZCConnection:286 : >> After node delete. USAGEG   1
INFO    | ZCWrapper.hpp   | runZCConnection:308 : >> END OF ONE TASK. USAGEG   0
INFO    | ZCWrapper.hpp   | runZCConnection:310 : connection buffer : 1
.
.
.
INFO    | ZCWrapper.hpp   | runZCConnection:315 : delete

Как мы можем решить проблему?
Заранее спасибо.

3

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]