PDA

View Full Version : QPixmaps don't seem to deallocate from memory(solved)



timothy.crosley
14th August 2007, 15:40
Solved :):
Apparently the problem wasn't in deallocating images, it was in the command I used to get the image location(the database->cell method) I didn't consider this because the dataCache also used the method. But here is what was going on, the "thumbnail" + thumbnailSize column was set as type "Icon" which meant the database would link to the icon database and from that the current icon theme database. When it linked it would call the index->set method to update the index to the correct location:

//Constructer
Index::Index(const QString &location, QObject *parent)
: AbstractIndex(location, parent)
{
set(location);
}

//Destructer
Index::~Index()
{/* Do nothing*/}

/*
*sets the index's location
*/
void Index::set(const QString &location)
{
index = new Storage(location + "/" + "index", this);
indexAll = new Storage(location + "/" + "index.all", this);
indexEntrys = new Storage(location + "/" + "index.entrys", this);
indexStartsWith = new Storage(location + "/" + "index.startswith", this);

}

so every time the set command was called all these storage objects would just be recreated without the old ones being deleted! I don't know how I made such a big mistake :o.

Thanks everyone for your help :).
~Timothy

Hi,
I have a method that fills a QList<QPixmap*> after attempting to delete its previous content:



QPixmapCache::clear();
thumbnails.clear();
for(int row = 0; row < currentRows.size(); row++)
{
QPixmap image(database->cell(currentRows.at(row), "thumbnail" + thumbnailSize));
thumbnails += image;
}

However when I look at the application on KSystemGaurd its ram usage raises by 1 meg everytime that method is called (I can get my application to use 2Gb of ram just by calling that method enough times) If I remove the following lines:

QPixmap *image = new QPixmap(database->cell(currentRows.at(row), "thumbnail" + thumbnailSize));
thumbnails += image;
the memory leak dissappears, what am I doing wrong?

Edit:
here is the entire method:

void DatabaseModel::display()
{
if(currentRows.size() > 0){
beginRemoveRows(QModelIndex(), 0, currentRows.size());
currentRows.clear();
endRemoveRows();
}

beginInsertRows(QModelIndex(), 0, currentRows.size());
qint64 currentOffset = 0;
currentRows = database->rows(positionCache.last(), maxShown, currentOffset);
qDeleteAll(dataCache);
dataCache.clear();
QPixmapCache::clear();
thumbnails.clear();
for(int row = 0; row < currentRows.size(); row++)
{
QStringList *rowData = new QStringList;
for(int col = 0; col < cols.size(); col++){
rowData->append(database->cell(currentRows.at(row), cols.at(col)));
}
dataCache += rowData;
QPixmap image(database->cell(currentRows.at(row), "thumbnail" + thumbnailSize));
thumbnails += image;
}

positionCache += currentOffset;
endInsertRows();
}

I am using the latest Qt update for kubuntu: 4.3.0-4.

Thanks in advance :),
~Timothy

marcel
14th August 2007, 15:48
Try a:


QPixmapCache::clear();

before qDeleteAll();

timothy.crosley
14th August 2007, 16:35
I really appreciate the quick response; sadly though, this didn't seem to change anything :(. I updated the question to reflect this.
~Timothy

jpn
14th August 2007, 17:34
QPixmap is an implicitly shared class (http://doc.trolltech.com/4.3/shared.html) so I'd suggest allocating pixmaps on stack for easier memory management.

timothy.crosley
14th August 2007, 17:46
How do I allocate the pixmaps on stack?
Thanks,
~Timothy

jpn
14th August 2007, 18:15
Without keyword "new":


QList<QPixmap> thumbnails;
...
// qDeleteAll(thumbnails); // remove this
thumbnails.clear();
...
QPixmap image = QPixmap(database->cell(currentRows.at(row), "thumbnail" + thumbnailSize));
thumbnails += image;

timothy.crosley
14th August 2007, 18:36
I should have known what you meant :o. Sadly this still doesn't fix the memory leak(I actually had it this way originally). I have been trying to fix this bug for 3 days now and its driving me insane :(.
~Timothy

spud
14th August 2007, 19:04
Since you mentioned the QPixmapCache, what does QPixmapCache::cacheLimit () return.

timothy.crosley
14th August 2007, 19:33
It returns 1024.

marcel
14th August 2007, 19:47
If you have the possibility, step in the QPixmap destructor and see if it deletes the data member.


void QPixmap::deref()
{
if(data && data->deref()) { // Destroy image if last ref
if (qt_pixmap_cleanup_hook_64)
qt_pixmap_cleanup_hook_64(cacheKey());
delete data;
data = 0;
}
}



Regards

jpn
15th August 2007, 21:49
What was the problem and how was it solved in the end?

Edit: Oh, sorry. I didn't notice the first post being modified.. :p

marcel
15th August 2007, 21:59
What was the problem and how was it solved in the end?

See the first post :).