QMovie leaking lots of pixmap resources

Maks Orlovich mo002j at mail.rochester.edu
Thu Jan 1 19:16:10 GMT 2004


On Thursday 01 January 2004 01:39 pm, Martijn Klingens wrote:
> On Thursday 01 January 2004 19:06, Dirk Mueller wrote:
> > they might be a trigger but not the cause. the pixmapcache size is
> > limited to 1MB in total, so it can't leak, even though you found an
> > inefficiency here (I agree the if should be changed to timer >= 0 && loop
> > >= 0).

<snip>
The attached two diffs may be helpful in debugging those things, as they let 
one dump all pixmaps over dcop. The first one applies to Qt; and although the 
change is local, it does touch qpixmap.h, so you may want to do touch -D "5 
years ago" qpixmap.h or such when applying. The other one adds a KDebug 
method to dump things; the diff also has an unrelated additional method, 
which I was too lazy to remove...

Anyway, if one applies them to Qt and kdecore, and prepares a clean /tmp/dump 
writeable by the user, doing things like dcop kopete KDebug dumpPixmaps will 
save all the pixmaps in memory to disk. Note that the black-blue ones are 
alpha masks associated with "real" pixmaps. 

Also, at any rate, there do seem to be an awful lot of the spinning Kopete 
logo pixmaps in there..

-Maks



-------------- next part --------------
diff -u -r qt-x11-free-3.3.0-snapshot-20031218/src/kernel/qpixmap.cpp qt-x11-free-3.3.0-snapshot-20031218.diff/src/kernel/qpixmap.cpp
--- qt-x11-free-3.3.0-snapshot-20031218/src/kernel/qpixmap.cpp	2003-12-17 20:50:20.000000000 -0500
+++ qt-x11-free-3.3.0-snapshot-20031218.diff/src/kernel/qpixmap.cpp	2003-12-30 20:05:03.000000000 -0500
@@ -128,7 +128,7 @@
 	QPixmap::setDefaultOptimization( QPixmap::NormalOptim );
     \endcode
 
-    In general it is recommended to make as much use of QPixmap's 
+    In general it is recommended to make as much use of QPixmap's
     implicit sharing and the QPixmapCache as possible.
 
     \sa QBitmap, QImage, QImageIO, \link shclass.html Shared Classes\endlink
@@ -164,7 +164,7 @@
     \value NoOptim  No optimization (currently the same as \c
 	MemoryOptim).
 
-    \value MemoryOptim  Optimize for minimal memory use on Windows 
+    \value MemoryOptim  Optimize for minimal memory use on Windows
 	9x and X11 systems.
 
     \value NormalOptim  Optimize for typical usage. Often uses more
@@ -178,6 +178,44 @@
 
 */
 
+#include "qmap.h"
+
+static QMap<QPixmap*, bool>* pixmapsMap = 0;
+
+static QMap<QPixmap*, bool>* pmap()
+{
+    if (!pixmapsMap)
+        pixmapsMap = new QMap<QPixmap*, bool>;
+    return pixmapsMap;
+}
+
+class PixSetDumper
+{
+public:
+    static void dump()
+    {
+        qDebug("Dump called, num pixmaps:%d", pmap()->size());
+        QMap<QPixmap::QPixmapData*, bool> dumpedData;
+
+        int pos = 0;
+        for (QMap<QPixmap*, bool>::iterator iter = pmap()->begin(); iter != pmap()->end(); ++iter)
+        {
+            qDebug("See pixmap:%dx%d@%x", iter.key()->width(), iter.key()->height(), iter.key()->data);
+            if (dumpedData.contains(iter.key()->data))
+                continue;
+            dumpedData[iter.key()->data] = true;
+            QString name = QString("/tmp/dump/%1.png").arg(pos);
+            qDebug("saving..%s", name.latin1());
+            iter.key()->convertToImage().save(name,"PNG");
+            pos++;
+        }
+    }
+};
+
+void dump_qt_pixmaps()
+{
+    PixSetDumper::dump();
+}
 
 QPixmap::Optimization QPixmap::defOptim = QPixmap::NormalOptim;
 
@@ -191,6 +229,7 @@
 		  Optimization optimization )
     : QPaintDevice( QInternal::Pixmap )
 {
+    (*pmap())[this] = true;
     init( w, h, depth, bitmap, optimization );
 }
 
@@ -204,6 +243,7 @@
 QPixmap::QPixmap()
     : QPaintDevice( QInternal::Pixmap )
 {
+    (*pmap())[this] = true;
     init( 0, 0, 0, FALSE, defOptim );
 }
 
@@ -216,6 +256,7 @@
 QPixmap::QPixmap( const QImage& image )
     : QPaintDevice( QInternal::Pixmap )
 {
+    (*pmap())[this] = true;
     init( 0, 0, 0, FALSE, defOptim );
     convertFromImage( image );
 }
@@ -239,6 +280,7 @@
 QPixmap::QPixmap( int w, int h, int depth, Optimization optimization )
     : QPaintDevice( QInternal::Pixmap )
 {
+    (*pmap())[this] = true;
     init( w, h, depth, FALSE, optimization );
 }
 
@@ -252,6 +294,7 @@
 QPixmap::QPixmap( const QSize &size, int depth, Optimization optimization )
     : QPaintDevice( QInternal::Pixmap )
 {
+    (*pmap())[this] = true;
     init( size.width(), size.height(), depth, FALSE, optimization );
 }
 
@@ -278,6 +321,7 @@
 	int conversion_flags )
     : QPaintDevice( QInternal::Pixmap )
 {
+    (*pmap())[this] = true;
     init( 0, 0, 0, FALSE, defOptim );
     load( fileName, format, conversion_flags );
 }
@@ -299,6 +343,7 @@
 QPixmap::QPixmap( const QString& fileName, const char *format, ColorMode mode )
     : QPaintDevice( QInternal::Pixmap )
 {
+    (*pmap())[this] = true;
     init( 0, 0, 0, FALSE, defOptim );
     load( fileName, format, mode );
 }
@@ -329,6 +374,7 @@
 QPixmap::QPixmap( const char *xpm[] )
     : QPaintDevice( QInternal::Pixmap )
 {
+    (*pmap())[this] = true;
     init( 0, 0, 0, FALSE, defOptim );
     QImage image( xpm );
     if ( !image.isNull() )
@@ -345,6 +391,7 @@
 QPixmap::QPixmap( const QByteArray & img_data )
     : QPaintDevice( QInternal::Pixmap )
 {
+    (*pmap())[this] = true;
     init( 0, 0, 0, FALSE, defOptim );
     loadFromData( img_data );
 }
@@ -357,6 +404,7 @@
 QPixmap::QPixmap( const QPixmap &pixmap )
     : QPaintDevice( QInternal::Pixmap )
 {
+    (*pmap())[this] = true;
     if ( pixmap.paintingActive() ) {		// make a deep copy
 	data = 0;
 	operator=( pixmap.copy() );
@@ -383,6 +431,7 @@
 
 QPixmap::~QPixmap()
 {
+    pmap()->remove(this);
     deref();
 }
 
Only in qt-x11-free-3.3.0-snapshot-20031218.diff/src/kernel: qpixmap.cpp~
diff -u -r qt-x11-free-3.3.0-snapshot-20031218/src/kernel/qpixmap.h qt-x11-free-3.3.0-snapshot-20031218.diff/src/kernel/qpixmap.h
--- qt-x11-free-3.3.0-snapshot-20031218/src/kernel/qpixmap.h	2003-12-17 20:50:17.000000000 -0500
+++ qt-x11-free-3.3.0-snapshot-20031218.diff/src/kernel/qpixmap.h	2003-12-30 19:27:46.000000000 -0500
@@ -264,6 +264,7 @@
     friend class QPaintDevice;
     friend class QPainter;
     friend class QGLWidget;
+    friend class PixSetDumper;
 };
 
 
Only in qt-x11-free-3.3.0-snapshot-20031218.diff/src/kernel: qpixmap.h~
diff -u -r qt-x11-free-3.3.0-snapshot-20031218/src/libqt.map qt-x11-free-3.3.0-snapshot-20031218.diff/src/libqt.map
--- qt-x11-free-3.3.0-snapshot-20031218/src/libqt.map	2003-12-17 20:49:49.000000000 -0500
+++ qt-x11-free-3.3.0-snapshot-20031218.diff/src/libqt.map	2003-12-30 19:49:37.000000000 -0500
@@ -2,6 +2,7 @@
   global:
   extern "C++"
   {
+    dump_qt_pixmaps*;
     QString::shared_null*;
     TID_QUType_Null*;
     TID_QUType_bool*;
-------------- next part --------------
Index: kdebugdcopiface.h
===================================================================
RCS file: /home/kde/kdelibs/kdecore/kdebugdcopiface.h,v
retrieving revision 1.2
diff -u -6 -p -r1.2 kdebugdcopiface.h
--- kdebugdcopiface.h	16 Aug 2003 19:44:57 -0000	1.2
+++ kdebugdcopiface.h	1 Jan 2004 19:00:54 -0000
@@ -36,10 +36,14 @@ public:
 k_dcop:
 	/**
 	 * The kdebugrc has been changed and should be reparsed now.
 	 * This will simply call kdClearDebugConfig
 	 **/
 	void notifyKDebugConfigChanged();
+	
+	void forceExit();
+	
+	void dumpPixmaps();
 };
 
 #endif
 
Index: kdebugdcopiface.cpp
===================================================================
RCS file: /home/kde/kdelibs/kdecore/kdebugdcopiface.cpp,v
retrieving revision 1.1
diff -u -6 -p -r1.1 kdebugdcopiface.cpp
--- kdebugdcopiface.cpp	29 Nov 2002 21:16:33 -0000	1.1
+++ kdebugdcopiface.cpp	1 Jan 2004 19:00:54 -0000
@@ -16,12 +16,13 @@
     the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
     Boston, MA 02111-1307, USA.
 */
 
 #include "kdebugdcopiface.h"
 #include "kdebug.h"
+#include <stdlib.h>
 
 KDebugDCOPIface::KDebugDCOPIface() : DCOPObject("KDebug")
 {
 }
 
 KDebugDCOPIface::~KDebugDCOPIface()
@@ -30,6 +31,17 @@ KDebugDCOPIface::~KDebugDCOPIface()
 
 void KDebugDCOPIface::notifyKDebugConfigChanged()
 {
  kdClearDebugConfig();
 }
 
+void KDebugDCOPIface::forceExit()
+{
+ ::exit(0);
+}
+
+extern void dump_qt_pixmaps();
+
+void KDebugDCOPIface::dumpPixmaps()
+{
+    dump_qt_pixmaps();
+}
\ No newline at end of file


More information about the kde-core-devel mailing list