PDA

View Full Version : Qt 4.1 Memory Leak



blackliteon
8th February 2006, 09:46
When I complime my qt project (VC++, using plugins, Win-XP) I saw interesting details about memory that my application used..
It's very strange, while I _only_ press menu button or change focus from other application to mine, size of memory used by my application Up and Up!
Is it Memory Leak, what do you think ?

high_flyer
8th February 2006, 11:28
very probable that its a memory leak.
But we can't say with out the code.

blackliteon
8th February 2006, 15:43
It's mostly all examples.
You can try to run pluginpaint example.
Then wait & seek after memory used (I test in WinXP)

Codepoet
8th February 2006, 15:53
That is the result of valgrind, a memory debugger, when running the plugandpaint example and doing some things like switching windows, painting something, using menu entries...

I'm testing under Linux.


valgrind --tool=memcheck --leak-check=full ./plugandpaint
==16772== Memcheck, a memory error detector for x86-linux.
==16772== Copyright (C) 2002-2005, and GNU GPL'd, by Julian Seward et al.
==16772== Using valgrind-2.4.0, a program supervision framework for x86-linux.
==16772== Copyright (C) 2000-2005, and GNU GPL'd, by Julian Seward et al.
==16772== For more details, rerun with: -v
==16772==
==16772== Conditional jump or move depends on uninitialised value(s)
==16772== at 0x1C229F47: store_to_database (in /usr/lib/libX11.so.6.2)
==16772==
==16772== Conditional jump or move depends on uninitialised value(s)
==16772== at 0x1C229F50: store_to_database (in /usr/lib/libX11.so.6.2)
==16772==
==16772== Conditional jump or move depends on uninitialised value(s)
==16772== at 0x1C229F9B: store_to_database (in /usr/lib/libX11.so.6.2)
==16772==
==16772== Conditional jump or move depends on uninitialised value(s)
==16772== at 0x1C229FA0: store_to_database (in /usr/lib/libX11.so.6.2)
==16772==
==16772== Syscall param write(buf) points to uninitialised byte(s)
==16772== at 0x1C470248: write (in /lib/libpthread-0.10.so)
==16772== Address 0x1C77F510 is 320 bytes inside a block of size 16384 alloc'd
==16772== at 0x1B904E9A: calloc (vg_replace_malloc.c:176)
==16772== by 0x1C1D0E09: XOpenDisplay (in /usr/lib/libX11.so.6.2)
==16772==
==16772== Syscall param writev(vector[...]) points to uninitialised byte(s)
==16772== at 0x1C6663AE: (within /lib/libc-2.3.6.so)
==16772== by 0x1C2036BD: _X11TransSocketWritev (in /usr/lib/libX11.so.6.2)
==16772== Address 0x1C77F45E is 142 bytes inside a block of size 16384 alloc'd
==16772== at 0x1B904E9A: calloc (vg_replace_malloc.c:176)
==16772== by 0x1C1D0E09: XOpenDisplay (in /usr/lib/libX11.so.6.2)
==16772==
==16772== ERROR SUMMARY: 90 errors from 6 contexts (suppressed: 86 from 2)
==16772== malloc/free: in use at exit: 974296 bytes in 7456 blocks.
==16772== malloc/free: 236588 allocs, 229132 frees, 66411306 bytes allocated.
==16772== For counts of detected errors, rerun with: -v
==16772== searching for pointers to 7456 not-freed blocks.
==16772== checked 1740280 bytes.
==16772==
==16772==
==16772== 20 bytes in 1 blocks are definitely lost in loss record 30 of 116
==16772== at 0x1B904368: malloc (vg_replace_malloc.c:130)
==16772== by 0x1C61D12F: strdup (in /lib/libc-2.3.6.so)
==16772== by 0x1BB33812: qt_init(QApplicationPrivate*, int, _XDisplay*, unsigned long, unsigned long) (in /usr/lib/qt4/libQtGui_debug.so.4.1.0)
==16772== by 0x1BAD0F4E: QApplicationPrivate::construct() (in /usr/lib/qt4/libQtGui_debug.so.4.1.0)
==16772== by 0x1BAD0B76: QApplication::QApplication(int&, char**) (in /usr/lib/qt4/libQtGui_debug.so.4.1.0)
==16772== by 0x804EE1C: (within /usr/share/doc/qt-4.1.0/examples/tools/plugandpaint/plugandpaint)
==16772== by 0x1C5CB554: __libc_start_main (in /lib/libc-2.3.6.so)
==16772== by 0x804EC50: (within /usr/share/doc/qt-4.1.0/examples/tools/plugandpaint/plugandpaint)
==16772==
==16772==
==16772== 68 bytes in 1 blocks are possibly lost in loss record 45 of 116
==16772== at 0x1B904E9A: calloc (vg_replace_malloc.c:176)
==16772== by 0x1B8F2148: allocate_dtv (in /lib/ld-2.3.6.so)
==16772== by 0x1B8F21FF: _dl_allocate_tls_storage (in /lib/ld-2.3.6.so)
==16772== by 0x1B8F2427: _dl_allocate_tls (in /lib/ld-2.3.6.so)
==16772== by 0x1C46B971: __pthread_initialize_minimal (in /lib/libpthread-0.10.so)
==16772== by 0x1C468314: ??? (crti.S:19)
==16772== by 0x1C467CEF: ??? (crti.S:32)
==16772== by 0x1B8EFB4D: call_init (in /lib/ld-2.3.6.so)
==16772== by 0x1B8EFCDD: _dl_init (in /lib/ld-2.3.6.so)
==16772== by 0x1B8E480E: (within /lib/ld-2.3.6.so)
==16772==
==16772==
==16772== 156 (36 direct, 120 indirect) bytes in 1 blocks are definitely lost in loss record 56 of 116
==16772== at 0x1B904368: malloc (vg_replace_malloc.c:130)
==16772== by 0x1C67CEF8: (within /lib/libc-2.3.6.so)
==16772== by 0x1C67C7F3: __nss_database_lookup (in /lib/libc-2.3.6.so)
==16772== by 0x1B9201EB: ???
==16772== by 0x1B921DA4: ???
==16772== by 0x1C63C9E3: getpwuid_r (in /lib/libc-2.3.6.so)
==16772== by 0x1C63C45E: getpwuid (in /lib/libc-2.3.6.so)
==16772== by 0x1BB3D5AD: (within /usr/lib/qt4/libQtGui_debug.so.4.1.0)
==16772== by 0x1BB3D2E9: (within /usr/lib/qt4/libQtGui_debug.so.4.1.0)
==16772== by 0x1C0B2DCA: _SmcProcessMessage (in /usr/lib/libSM.so.6.0)
==16772==
==16772==
==16772== 2720 bytes in 1 blocks are possibly lost in loss record 105 of 116
==16772== at 0x1B905096: memalign (vg_replace_malloc.c:217)
==16772== by 0x1B8F21D1: _dl_allocate_tls_storage (in /lib/ld-2.3.6.so)
==16772== by 0x1B8F2427: _dl_allocate_tls (in /lib/ld-2.3.6.so)
==16772== by 0x1C46B971: __pthread_initialize_minimal (in /lib/libpthread-0.10.so)
==16772== by 0x1C468314: ??? (crti.S:19)
==16772== by 0x1C467CEF: ??? (crti.S:32)
==16772== by 0x1B8EFB4D: call_init (in /lib/ld-2.3.6.so)
==16772== by 0x1B8EFCDD: _dl_init (in /lib/ld-2.3.6.so)
==16772== by 0x1B8E480E: (within /lib/ld-2.3.6.so)
==16772==
==16772== LEAK SUMMARY:
==16772== definitely lost: 56 bytes in 2 blocks.
==16772== indirectly lost: 120 bytes in 10 blocks.
==16772== possibly lost: 2788 bytes in 2 blocks.
==16772== still reachable: 971332 bytes in 7442 blocks.
==16772== suppressed: 0 bytes in 0 blocks.
==16772== Reachable blocks (those to which a pointer was found) are not shown.
==16772== To see them, rerun with: --show-reachable=yes

Looks like everything is ok ;)

The Qt runtime allocates sometimes more memory to create new instances and releases these when they are no longer needed. An example are popup menus.

blackliteon
8th February 2006, 23:44
THanks for description.
And one moment i saw (not so bad)
When you minimize window? size of allocated memory changed to 1mb
Perfect!

wysota
9th February 2006, 00:58
malloc/free: in use at exit: 974296 bytes in 7456 blocks.

There is almost a megabyte on unfreed but reachable memory :) So there is a leak, but looks like it's not in Qt but rather somewhere in XLib and libc.

blackliteon
9th February 2006, 14:33
There is almost a megabyte on unfreed but reachable memory :) So there is a leak, but looks like it's not in Qt but rather somewhere in XLib and libc.
In most cases I think that's application allocate more memory

Codepoet
9th February 2006, 14:54
There is almost a megabyte on unfreed but reachable memory :) So there is a leak, but looks like it's not in Qt but rather somewhere in XLib and libc.
It's in several libraries, part of them Qt. But this kind of leak will probably not increase while your program is running because it could have been freed.

I've attached another valgrind run with more details.

wysota
9th February 2006, 15:00
In most cases I think that's application allocate more memory

The thing is this memory is unfreed upon program termination, which is considered a leak. I don't investigate how much memory does the process allocate during its life.

BTW: "malloc/free: 236588 allocs, 229132 frees, 66411306 bytes allocated."

blackliteon
9th February 2006, 15:14
The thing is this memory is unfreed upon program termination, which is considered a leak. I don't investigate how much memory does the process allocate during its life.

BTW: "malloc/free: 236588 allocs, 229132 frees, 66411306 bytes allocated."
Sure you right!

Codepoet
9th February 2006, 15:38
We need another tool here: Valgrind gives only total statistics not time samples and peak memory usage. Does anybody know of such a tool?

blackliteon
9th February 2006, 18:16
We need another tool here: Valgrind gives only total statistics not time samples and peak memory usage. Does anybody know of such a tool?
You mean memory leak or speed ?

Codepoet
9th February 2006, 18:52
Valgrind is slow, yes - but that is not the reason: Valgrind does not collect statistics about things like:

maximum amount of memory used
memory usage while the application runs
graph of used memory by elapsed time

These 66MB are the total amount of memory the program allocated during the whole run. But we are interested in how much did it use at any given time. That is a big difference since memory is freed again, then allocated and so on. We have many short lived objects.

At the moment I'm trying memprof but it crashes :(

wysota
9th February 2006, 22:25
Limit resources which can be given to a single process to a known amount, and you'll get info if the limit was met. See manual for ulimit for details. Or try mpatrol. Or do your own statistics, for example by overriding new and delete and using LD_PRELOAD.

Codepoet
10th February 2006, 13:47
When running plugandpaint under mpatrol it's horribly slow, even slower then valgrind. Somewhere in mpatrol seems to be a bug because I constantly get errors about memmove on freed memory :confused:
Nevertheless I've got some numbers: around 3.5 MB peak memory usage of plugandpaint


I'll probably write my own library because I need one for my own job in the long term.