LINUX.ORG.RU

[Qt][TcpSocket]Утечки памяти

 


0

2

Здравствуйте. Прошу помочь в поиске решения проблемы. Имею устройство с которым связываюсь по Tcp стучусь на 10000-й порт. Порт точно открыт соединение точно происходит. Далее идет сеанс обмена данными(или не идет, по ситуации) после чего соединение закрывается.

Приложение вроде работает но со временем приложение начинает есть все больше и больше памяти.

В связи с чем написал небольшую аппликуху, которая устанавливает и тут же рвет соединение с переодичностью в 1 секунду.

Сомнения подтвердились память течет.

Вопрос как сделать так чтобы не текла.

Течет в процессе работы приложения. new QTcpSocket вызывается только один раз и потому эта память в расчетах не участвует.

Версия qt 4.7.4 Среда Виндовс.

Под линем еще не проверял. Но линуксовая тачка с конечным приложением будет стоять в закрытом шкафу и хочется сделать ее максимально стабильной.

Листинг: main.cpp

#include <QtCore/QCoreApplication>
#include <nettest.h>


int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    nettest nt;
    nt.timerid = nt.startTimer(20000);

    return a.exec();
}

nettest.h

#ifndef NETTEST_H
#define NETTEST_H

#include <QObject>
#include <QtNetwork>

class nettest : public QObject
{
    Q_OBJECT
public:
    explicit nettest(QObject *parent = 0);
    QTcpSocket * sock;
    int timerid;
    void get_currentdata(QString ipaddr, int port);
signals:

public slots:
    void timerEvent(QTimerEvent * te);
};

#endif // NETTEST_H

nettest.cpp

#include "nettest.h"

nettest::nettest(QObject *parent) :
    QObject(parent)
{
    sock = new QTcpSocket;
}

void nettest::timerEvent(QTimerEvent *te){
    if (timerid==te->timerId()){
        killTimer(timerid);
        get_currentdata("192.168.0.196",10000);
        timerid=this->startTimer(1000);
    }
}

void nettest::get_currentdata(QString ipaddr, int port) {
    sock->connectToHost(ipaddr,port);
    if (sock->waitForConnected(10000))
    {
        sock->close();
    }
}



Последнее исправление: iTroll (всего исправлений: 2)

А можно узнать размеры утечек? а то я повторил в точности ваш код, жду уже минут 10, но никакого роста используемой памяти не вижу...

Daeloce
()

Valgrind в помощь. Твой пример если и течет, то это не твоя вина (не считая неудаленного QTcpSocket).

anonymous
()
Ответ на: комментарий от Daeloce

Стекат потихоньку по 4 килобайта. У меня наблюдается через минут 10.

Видно в диспетчере задач. Можно ускорить если timerid=this->startTimer(1000); поменять на timerid=this->startTimer(100);

В момент connectToHost Выделяется добуя памяти. Потом освобождается после дисконнекта.

я засекал по скачкам, давал минуту на разкочегаривание, потом засекал минимальное и максимальное значение.

Спустя где то 10 минут минимальное нарастало на 4 килобайта, затем минимальное.

Если не секрет какая версия QT у тебя?

iTroll
() автор топика
Ответ на: комментарий от iTroll

Если не секрет какая версия QT у тебя?

Во-первых, Qt, а во-вторых, прозреваю вендопроблемы.

anonymous
()
Ответ на: комментарий от panter_dsd

Диспетчером задач. Пробовал еще processExplorer. там в properties в performance есть Physical Memory. Особо наблюдаемо поле WorkingSet.

iTroll
() автор топика

QTcpSocket может создавать какие-то объекты во время connectToHost() и привязывать их к себе (в смысле parent), но не удаляет эти объекты. Они как бы должны удаляться, но только когда вызваеться деструктор QTcpSocket. А поскольку ты его не удаляешь, эти привязаные, уже не нужные объекты, не удаляются.

Но это догадка в общем-то. Не факт что это так. Что бы опровергнуть, попробуй создавать новый QTcpSocket при каждом коннекте, а при закрытии сокета удалять его explicitly.

anonymous
()
Ответ на: комментарий от iTroll

У меня виндовс, а valgrind вроде как только под линукс, или есть альтернативы?

Есть, но я про них не очень в курсе. Не так давно гуглил что-то интеловское, но оно платное, хотя вроде было 30 дней триала, + варез на торрентах. VTune, если память не изменяет.

Вот еще:
http://stackoverflow.com/questions/413477/is-there-a-good-valgrind-substitute...

anonymous
()
Ответ на: комментарий от anonymous

На сейчас сделал так, тестирую

nettest::nettest(QObject *parent) :
    QObject(parent)
{
}

void nettest::timerEvent(QTimerEvent *te){
    if (timerid==te->timerId()){
        killTimer(timerid);
        get_currentdata("192.168.0.196",10000);
        timerid=this->startTimer(200);
    }
}

void nettest::get_currentdata(QString ipaddr, int port) {
    QTcpSocket * sock = new QTcpSocket();
    sock->connectToHost(ipaddr,port);
    if (sock->waitForConnected(10000))
    {
        if (sock->size()>0){
            sock->readAll();
        }
        sock->close();
    }
    sock->abort(); //на всякий случай
    delete sock;
}
За 5 минут утекло 4 килобайта (или может меньше но в винде память выделяется блоками по 4 к).

к концу первой минуты было на старте минимальное колво памяти было 4344 к Теперь 4348

из них локальный минимум по ws Shareable было 3508 стало 3512 а WS Shared было 1916 стало 1920.

Тоесть растет Память которая WS Shared. Приватная(WS Private) остается неизменной.

iTroll
() автор топика
Ответ на: комментарий от anonymous

QTcpSocket может создавать какие-то объекты во время connectToHost() и привязывать их к себе (в смысле parent)

Если бы так было, то скорее всего в линупсе тоже бы текло, но так как течка только в венде у ОПа, то либо кутешный вендокод течет, либо где-то у ОПа.

anonymous
()
Ответ на: комментарий от anonymous

Завтра разверну линупс с валгриндом в виртуалке и потещщу.

iTroll
() автор топика

ИТОГО

Загнал исходник на линуксовую тачку. Скомпил в QTCreatore, запустил анализ валгриндом. Прогнал 16,5 часов валгринд сказал утечек не обнаружено (во всяком случае моих, когда ставишь «Внешние ошибки» там чего то высвечивается ругается на main.cpp, а так тишина).

Под виндой оставил приложение на 48 часов. Память периодически утекает, но со временем возвращается в свое русло. Итого совместными усилиями (с коллегой) пришли к выводу что проблема не существенна, но как то сыкотно.

iTroll
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.