Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Calling connect() signal slot based on timeout consuming lot of memory



  • HI All,
    Good Afternoon.
    Does anybody having solution to this Problem that I am facing in Qt Windows.

    When I am calling below piece of code from my class constructor to flash a widget, its consuming lots of memory. It reaches upto 90MB in 24 hours and aroung 200MB in 48 hours. If I am not calling this piece of code then memory consumption doesnt go beyong 39MB:

    CYardView::CYardView()
    {
    m_Timer=new QTimer();
    m_Timer->setInterval(1200);
    m_Timer->start();
    connect(m_Timer, SIGNAL(timeout()), this, SLOT(FlashSkateObject()));
    }
    void CYardView::FlashSkateObject()
    {
    QList<QString> IndicatorName = m_IndicatorStateListHandler->FlashingIndicatorList();
    if (IndicatorName.size()>0)
    {
    for(int i=0;i<IndicatorName.size();i++)
    {
    for (int j = 0; j < m_RetarderList->count(); j++)
    {
    if (m_RetarderList->at(j)->GetRetarderName() == IndicatorName.at(i))
    {
    if(m_RetarderList->at(j)->getIsPulse())
    {
    m_RetarderList->at(j)->setIsPulse(false);
    }
    else
    {
    m_RetarderList->at(j)->setIsPulse(true);
    }
    break;
    }
    }
    }
    }
    }

    Thanks



  • @ndiwan
    What is the difference if you remove all the code from the body of the slot?



  • Hi JonB,
    I haven't tried removing all code from the body of Slot. Code inside the body is just iterating though all widgets that I have and Setting pulse to false, So that Widget will flash. But I will try removing that code and then will see the memory consumption.

    Thanks



  • @ndiwan it may be your flash code has issues. How do you flash your widget? Toggle images or repaint? If images are toggled, check if the images are destroyed after toggle. If your app is on Linux, run valgrind and you will be able to see where the problem could be. On Windows, check this out.
    https://forum.qt.io/topic/124823/memory-leak-in-qt-4-10-0/30



  • Hi All,

    Good Morning. I checked that if i comment my Slot Function definition completely then memory is not hiking.
    But I am not Sure whats the problem here. In my Slot function definition, I am iterating through all my widgets and then drawing a rectangle round my widget if pulse it set to true:

    CYardView::CYardView()
    {
    m_Timer=new QTimer();
    m_Timer->setInterval(CConfigureApp::GetConfigureAppObject()->GetSkateRetarderPulseTimer());
    m_Timer->start();
    connect(m_Timer, SIGNAL(timeout()), this, SLOT(FlashSkateObject()));
    }

    void CYardView::FlashSkateObject()
    {
    for(int i=0 ; i < m_RetarderList->size() ;i++)
    {
    if(m_RetarderList->at(i)->getIsPulse() )
    {
    m_RetarderList->at(i)->setIsPulse(false);
    }
    else
    {
    m_RetarderList->at(i)->setIsPulse(true);
    }
    }

    Here m_RetarderList is of type QList<CSkateRetarder*> *m_RetarderList;

    Thanks



  • @ndiwan
    So now comment out just the setIsPulse()s, leaving the iterating lines in there....

    I assume this will not leak? So then your problem is in whatever setIsPulse() does. So nothing to do with timers, connects, your widget hierarchy, etc.



  • @ndiwan There may be many reason why this code is consuming memory!

    But I think it is not in the part you are showing us ;)

    First, where do you free the m_Timer instance?
    Second what does exactly FlashingIndicatorList()?
    It returns a QList<QString> - which could/should be a QStringList ;) - but interns, do you are doing dynamic allocation? Do you free all items after?

    Your for loops could also be much easier to read with a little code rewriting:

        for(const auto& name : qAsConst(IndicatorName))
        {
            for(const auto retarder : qAsConst(*m_RetarderList))
            {
                if (retarder->GetRetarderName() == name)
                {
                    retarder->setIsPulse(!retarder->getIsPulse());
                    // ==> I would add a TogglePulse() method to base class ;)
                    break;
                }
            }
        }
    

    Same remark with setIsPulse().



  • Hi,

    m_Timer and all other dynamic memory allocations are getting free inside desctructor .But problem is destructor will call only when i close my App/logout from my application.
    I think its not memory leaking issue, Instead it consuming memory coninuously because in every 1.2 seconds I am calling my Slot function which is iterating 12 times.

    Thanks



  • @ndiwan said in Calling connect() signal slot based on timeout consuming lot of memory:

    Instead it consuming memory coninuously because in every 1.2 seconds I am calling my Slot function which is iterating 12 times.

    I have many applications which are using QTimer, and slots are called very often. They do not consume memory because of that. They are running 24/7!

    So your memory leak is not because you are calling a slot, but because of the code executed in the slot.



  • Thanks All for your help and suggestions. I will try to optimize the code inside my Slot function.

    Thanks



  • @ndiwan said in Calling connect() signal slot based on timeout consuming lot of memory:

    I will try to optimize the code inside my Slot function.

    It is not a mater of code optimization.
    You are allocation object dynamically but never release them, as you don't show us the code, we cannot say where you are doing this.
    Take a closer look at:

    • FlashingIndicatorList()
    • GetRetarderName()
    • getIsPulse()
    • setIsPulse()


  • ok KroMignon. Thanks. I checked Inside slotting function, inside any API there is no dynamic memory allocation.Here is the definition of each inside Sloting function:

    QList<QString> CIndicatorStateListHandler::FlashingIndicatorList() const
    {
    return m_FlashingIndicatorList;
    }

    QString CSkateRetarder::GetRetarderName()
    {
    return m_qsRetarderName;
    }

    bool CSkateRetarder::getIsPulse() const
    {
    return m_isPulse;
    }

    void CSkateRetarder::setIsPulse(bool isPulse)
    {
    m_isPulse = isPulse;
    }

    HERE I am not allocating memory for any of the member dynamically.

    Also for the loop i optimize the code in the way you suggested.

    Thanks
    Nitin



  • Even if I replace my Slot function with below code, Memory is continuosly growing:

    void CYardView::FlashSkateObject()
    {
    for(const auto retarder : qAsConst(*m_RetarderList))
    {
    retarder->setIsPulse(!retarder->getIsPulse());
    }

    }

    Thanks


  • Lifetime Qt Champion

    Strip down your program until no leak occur anymore or until it's so minimal so that you can post it here. A timer does not leak memory (and especially not that much that you notice it in a few seconds). What leak detection tool do you use?


Log in to reply