PDA

View Full Version : Memory is not full released after deleting all QPushButtons in QTApp



asimfile
22nd September 2016, 07:01
i am creating a program containing QPushButtons, the Problem is when i am adding QPushButtons memory(RAM) increasing but when i deleted all added buttons memory is not fully releasing.


void TempTest ::addSLOT()
{
li= new QList<QPushButton*>;
for(int i=0;i<50000;i++)
{
QPushButton *p = new QPushButton;
p->setText("sample");
p->setFixedSize(100,100);
li->append(p);
}
}
void TempTest ::removeSLOT()
{
while(li->count())
{
QPushButton*p= li->at(0);
li->removeAt(0);
delete p;
}
delete li;
}

1.initialy memory is 2.0 mb

2.after adding memory increased to 49.3 mb

3.after deleting memory decreased to 4.1 mb

there is 2.1 mb of RAM it never released

anda_skoa
22nd September 2016, 07:28
You could have a leak elsewhere as this is definitely fine.

More likely though everything is fine, but your method of measuring is not accurate enough, e.g. looking at system memory usage UI.

Cheers,
_

asimfile
22nd September 2016, 08:42
thanks for reply
i am checking Ram in Windows Task manager, there is Memory column there.
i was having Ram issue in some other project thatswhy i write this sample code to check if All memory releasing or not.

Moreover if i repeat that process--
again add and delete Buttons - 4.4 mb
again add and delete Buttons - 4.9 mb
again add and delete Buttons - 4.6 mb
again add and delete Buttons - 4.4 mb
again add and delete Buttons - 5.4 mb
again add and delete Buttons - 4.9 mb
again add and delete Buttons - 4.6 mb

we can clearly see variations in memory but it never goes back to 2.0 mb

d_stranz
22nd September 2016, 17:18
we can clearly see variations in memory but it never goes back to 2.0 mb

As your program runs, Windows will allocate memory from the heap each time you call operator new(). When you call operator delete(), Windows will mark the memory as "available" again. However, if you do many allocations and deletions, the heap can become fragmented - there are pieces of the heap that are too small to be allocated for the object you wish to create, so Windows must grow the heap to find enough memory for the new allocation.

Windows memory management does have methods for compacting the heap - if you free two pieces of memory that are next to each other in the heap, then Windows will combine those two pieces into a single block. However, Windows memory management will never move active objects around on the heap to make more space - once you get a pointer to an allocated object, that pointer will never change during the lifetime of the object. This is what causes fragmentation - pieces of active memory between pieces of available memory. The active memory can't be touched, so the pieces in between can't be used either if they are too small.

The bottom line is that any program that allocates memory from the heap will most likely never go back to its lowest level so long as any heap is being used. Even if your program deletes all of the objects -it- has created, there are still internal allocation made by Qt which affect the heap. So you will see exactly what you are seeing - the program grows and shrinks, but never shrinks back to the base level. This is normal behavior.

What you need to worry about is if your program continues to grow with time. This often means you have a memory leak, but it could be also due to the fact that as your program runs, it is just using more resources to store its data. (For example, if you keep an "undo" stack, then each action will add to the stack and it will continue to grow).

In the code you posted, you are allocating two pieces of memory with each pass through the loop: one for the QPushButton instance, and another to extend the QList to hold the QPushButton instance pointer. Likewise, in the deletion routine, you are freeing up that memory, but probably not in the same way. QList might keep some memory allocated so it doesn't have to grow again, so just because you have deleted the button and removed it from the list, this does not mean that the QList has also shrunk its memory footprint. After all, QList is designed to be dynamic - items being added and removed all the time, so it is probably optimized to ask for new memory only when needed, and may not free up memory that it no longer is using at that moment. Thus, you get fragmentation.

As anda_skoa says, Task Manager is a crude tool for measuring the memory being used by a program. It only looks at how big the total heap is for a program, and is not updated frequently enough if your program is making rapid allocations and deleetions.

asimfile
24th September 2016, 11:29
As your program runs, Windows will allocate memory from the heap each time you call operator new(). When you call operator delete(), Windows will mark the memory as "available" again. However, if you do many allocations and deletions, the heap can become fragmented - there are pieces of the heap that are too small to be allocated for the object you wish to create, so Windows must grow the heap to find enough memory for the new allocation.

Windows memory management does have methods for compacting the heap - if you free two pieces of memory that are next to each other in the heap, then Windows will combine those two pieces into a single block. However, Windows memory management will never move active objects around on the heap to make more space - once you get a pointer to an allocated object, that pointer will never change during the lifetime of the object. This is what causes fragmentation - pieces of active memory between pieces of available memory. The active memory can't be touched, so the pieces in between can't be used either if they are too small.

The bottom line is that any program that allocates memory from the heap will most likely never go back to its lowest level so long as any heap is being used. Even if your program deletes all of the objects -it- has created, there are still internal allocation made by Qt which affect the heap. So you will see exactly what you are seeing - the program grows and shrinks, but never shrinks back to the base level. This is normal behavior.

What you need to worry about is if your program continues to grow with time. This often means you have a memory leak, but it could be also due to the fact that as your program runs, it is just using more resources to store its data. (For example, if you keep an "undo" stack, then each action will add to the stack and it will continue to grow).

In the code you posted, you are allocating two pieces of memory with each pass through the loop: one for the QPushButton instance, and another to extend the QList to hold the QPushButton instance pointer. Likewise, in the deletion routine, you are freeing up that memory, but probably not in the same way. QList might keep some memory allocated so it doesn't have to grow again, so just because you have deleted the button and removed it from the list, this does not mean that the QList has also shrunk its memory footprint. After all, QList is designed to be dynamic - items being added and removed all the time, so it is probably optimized to ask for new memory only when needed, and may not free up memory that it no longer is using at that moment. Thus, you get fragmentation.

As anda_skoa says, Task Manager is a crude tool for measuring the memory being used by a program. It only looks at how big the total heap is for a program, and is not updated frequently enough if your program is making rapid allocations and deleetions.

it very helpful, now i know that OS is responsible for this memory issues. Thanks for reply.