Pixmap memory consumption
Hey there, I'm developping a Qt app.
At some point in my application I'm loading 500 widgets and 1000 pixmap inside of it.
Since some pictures appears 2+ times, I've created a Pixmap "pool" manager to load once and for all a given Pixmap.
Here are the figures, compiled in static release :
at the beginning : my app takes 10 000 K of memory.
when 1000 Pixmap + Widgets loaded : my app takes 32 000 K of memory.
when unloaded : my app STILL takes 32 000 K of memory (if my Vista control panel is right).
I'm pretty sure I've deleted everything.
I'm not sure what could eat up so much memory since my "Pixmap manager" claims to contain 10 pixmap at the end.
Re: Pixmap memory consumption
Hard to say without seeing actual code. Did you explicitely call delete on every widget and pixmap? Or what do you mean by "being sure" they got deleted?
Re: Pixmap memory consumption
Here is my getPixmap function
Code:
//=============================================================================
//=============================================================================
int width,
int height)
{
ZeLog::get()->Print("ZePixmapManager - getPixmap 2 %s %d %d\n",
pixmapName.toStdString().c_str(), width, height);
if (tempPixmap.isNull())
{
tempPixmap
= QPixmap(PICTURE_DEFAULT
);
pixmapName = PICTURE_DEFAULT;
}
for (unsigned int i = 0; i < mPixmapItem.size(); i++)
{
if (mPixmapItem[i]->getPixmapName() == pixmapName
&&
mPixmapItem[i]->width() == width
&&
mPixmapItem[i]->height() == height)
{
ZeLog::get()->Print("ZePixmapManager - Pixmap already exists\n");
mPixmapItem[i]->addInstance();
return mPixmapItem[i]->getPixmap();
}
}
ZePixmapItem * pixmapItem = new ZePixmapItem(pixmapName,
tempPixmap.
scaled(width, height,
Qt::IgnoreAspectRatio,
Qt::SmoothTransformation));
mPixmapItem.push_back(pixmapItem);
ZeLog::get()->Print("ZePixmapManager - getPixmap %d %d\n",
pixmapItem->getPixmap().width(),
pixmapItem->getPixmap().height());
return pixmapItem->getPixmap();
}
and my delete pixmap :
Code:
//=============================================================================
//=============================================================================
bool ZePixmapManager
::DeletePixmap(const QString & pixmapName,
{
ZeLog::get()->Print("ZePixmapManager - DeletePixmap %d %s %d %d\n",
mPixmapItem.size(),
pixmapName.toStdString().c_str(),
pixmap.width(),
pixmap.height());
for (unsigned int i = 0; i < mPixmapItem.size(); i++)
{
if (mPixmapItem[i]->getPixmapName() == pixmapName
&&
mPixmapItem[i]->width() == pixmap.width()
&&
mPixmapItem[i]->height() == pixmap.height())
{
ZeLog::get()->Print("ZePixmapManager - DeletePixmap instance %d\n",
mPixmapItem[i]->getInstance());
mPixmapItem[i]->deleteInstance();
if (mPixmapItem[i]->getInstance() == 0)
{
ZeLog::get()->Print("ZePixmapManager - DeletePixmap complete\n");
delete mPixmapItem[i];
mPixmapItem.remove(i);
}
return true;
}
}
return false;
}
And here is my pixmap item :
Code:
//=============================================================================
//=============================================================================
// ZePixmapItem
//=============================================================================
//=============================================================================
ZePixmapItem
::ZePixmapItem(const QString & pixmapName,
mPixmapName(pixmapName),
mPixmap(pixmap)
{
mWidth = mPixmap.width();
mHeight = mPixmap.height();
mInstance = 0;
addInstance();
}
//=============================================================================
//=============================================================================
ZePixmapItem::~ZePixmapItem()
{
}
//=============================================================================
//=============================================================================
void ZePixmapItem::addInstance()
{
mInstance++;
}
//=============================================================================
//=============================================================================
void ZePixmapItem::deleteInstance()
{
mInstance--;
}
Re: Pixmap memory consumption
Quote:
Originally Posted by
bunjee
for (unsigned int i = 0; i < mPixmapItem.size(); i++)
{
...
mPixmapItem.remove(i);
...
}
When you remove item from the list, all items after it are shifted from position n+1 to n, but you always increment i. Which means that every time you remove something, you also skip the next item.
Re: Pixmap memory consumption
What about deleting widgets? We haven't seen any widget related code.
Re: Pixmap memory consumption
To jacek:
Code:
if (mPixmapItem[i]->getPixmapName() == pixmapName
&&
mPixmapItem[i]->width() == pixmap.width()
&&
mPixmapItem[i]->height() == pixmap.height())
{
ZeLog::get()->Print("ZePixmapManager - DeletePixmap instance %d\n",
mPixmapItem[i]->getInstance());
mPixmapItem[i]->deleteInstance();
if (mPixmapItem[i]->getInstance() == 0)
{
ZeLog::get()->Print("ZePixmapManager - DeletePixmap complete\n");
delete mPixmapItem[i];
mPixmapItem.remove(i);
}
return true;
}
I see what you mean, even though I'm not sure that's an issue since I'm returning true right after deleting an item, so the rest of the list is never checked.
Re: Pixmap memory consumption
Quote:
Originally Posted by
wysota
What about deleting widgets? We haven't seen any widget related code.
Actually I'm using a settable widget class of my own and I can certify its dtor is called :
Code:
//=============================================================================
//=============================================================================
ZeSettableLayout
::ZeSettableLayout(QWidget * parent
) :mLayout(this)
{
mSettableLayout = 0;
mWidget = 0;
getLayout().setMargin(0);
getLayout().setSpacing(0);
mOldParent = NULL;
}
//=============================================================================
//=============================================================================
ZeSettableLayout::~ZeSettableLayout()
{
Clear();
}
//=============================================================================
//=============================================================================
void ZeSettableLayout
::setLayout(QLayout & settableLayout,
int stretch)
{
Clear();
mSettableLayout = &settableLayout;
getLayout().addLayout(mSettableLayout, stretch);
}
//=============================================================================
//=============================================================================
void ZeSettableLayout
::setWidget(QWidget & widget,
int stretch,
Qt::Alignment alignment)
{
Clear();
mWidget = &widget;
// Saving old parent to restor it at deletion
mOldParent = getWidget().parentWidget();
getLayout().addWidget(mWidget, stretch, alignment);
getWidget().show();
}
//=============================================================================
//=============================================================================
void ZeSettableLayout::Clear()
{
if (mSettableLayout)
{
getLayout().removeItem(mSettableLayout);
mSettableLayout = NULL;
}
if (mWidget)
{
getLayout().removeWidget(mWidget);
// Retoring old parent for deletion
getWidget().setParent(mOldParent);
mOldParent = NULL;
//getWidget().hide();
mWidget = NULL;
}
update();
}
I have to reset Widget's parent everytime I set another one, otherwise its still parented to my settable layout class.
Maybe doing so prevent QT from freeing anything ? even when calling delete?
Re: Pixmap memory consumption
But do you call delete anywhere?
Re: Pixmap memory consumption
to wysota,
Yes here :
Code:
//=============================================================================
//=============================================================================
void ZeServiceContactList::clearContact()
{
ZeLog::get()->Print("ZeServiceContactList - Clearing contacts\n");
for (unsigned int i = 0; i < mContactVector.size(); i++)
{
mOfflineExpand.RemoveWidget(*(mContactVector[i]));
emit removeWidget(*(mContactVector[i]));
ZeQuickViewController::get()->getDynamicInterface().
deleteMatch(mContactVector[i]->getStatusBubble());
ZeQuickViewController::get()->getDynamicInterface().
deleteMatch(mContactVector[i]->getPictureWidget());
// Deleting widgets...
delete mContactVector[i];
delete mContactPopVector[i];
delete mContactPictureVector[i];
// Deleting widgets...
}
mContactVector.clear();
mContactPopVector.clear();
mContactPictureVector.clear();
}
Re: Pixmap memory consumption
The problem could be completely elsewhere. Actually, not a problem. If Vista has a good memory allocator, it won't deallocate freed memory in case the application wants it back later. You could try running another application that is memory exhaustive and see if the amount of memory allocated for the first app starts decreasing.