Development/Tutorials/Debugging/Shared Memory Usage in KDE: Difference between revisions

From KDE TechBase
m (Fix syntax highlighting.)
Line 38: Line 38:


'''main.cpp'''
'''main.cpp'''
<code cppqt>
<syntaxhighlight lang="cpp-qt">
#include <KAboutData>
#include <KAboutData>
#include <KApplication>
#include <KApplication>
Line 58: Line 58:
     return 0;
     return 0;
}
}
</code>
</syntaxhighlight>
'''CMakeLists.txt'''
'''CMakeLists.txt'''
<code>
<pre>
project (tutorial1)
project (tutorial1)
find_package(KDE4 REQUIRED)
find_package(KDE4 REQUIRED)
Line 69: Line 69:
target_link_libraries(tutorial1 ${KDE4_KDEUI_LIBS})
target_link_libraries(tutorial1 ${KDE4_KDEUI_LIBS})
install(TARGETS tutorial1  ${INSTALL_TARGETS_DEFAULT_ARGS})
install(TARGETS tutorial1  ${INSTALL_TARGETS_DEFAULT_ARGS})
</code>
</pre>
Compile and linkthis program:
Compile and linkthis program:
cmake . && make -j4
<pre>
cmake . && make -j4
</pre>
Run it:
Run it:
./tutorial1 &
<pre>
[3] 22733
./tutorial1 &
[3] 22733
</pre>
In this case the program gets the process ID 22733. We look at its memory consumption:
In this case the program gets the process ID 22733. We look at its memory consumption:
cat /proc/22733/status
<pre>
VmRSS:    19772 kB
cat /proc/22733/status
VmData:    5776 kB
VmRSS:    19772 kB
VmStk:        84 kB
VmData:    5776 kB
VmExe:        8 kB
VmStk:        84 kB
VmLib:    26804 kB
VmExe:        8 kB
VmLib:    26804 kB
</pre>
If we change the "100000" in the program code to "1", we get a different picture:
If we change the "100000" in the program code to "1", we get a different picture:
VmRSS:    16624 kB
<pre>
VmData:    2652 kB
VmRSS:    16624 kB
VmStk:        84 kB
VmData:    2652 kB
VmExe:        8 kB
VmStk:        84 kB
VmLib:    26804 kB
VmExe:        8 kB
So we see the heap is counted to "VmData" and contained in VmRSS.
VmLib:    26804 kB
</pre>
So we see the heap is counted to <tt>VmData</tt> and contained in <tt>VmRSS</tt>.


== Further Information ==
== Further Information ==


More information about this topic can be found in the article about [http://ktown.kde.org/~seli/memory/analysis.html memory usage analysis].
More information about this topic can be found in the article about [http://ktown.kde.org/~seli/memory/analysis.html memory usage analysis].

Revision as of 15:37, 27 June 2011

It is unfortunate that a lot of people don't understand the UNIX memory model. Unfortunately this is helped by tools like ps which are not able to provide accurate information about memory usage. In UNIX a process uses basically three kinds of memory segments: shared memory segments, code segments and data segments.

Shared memory is used by shared libraries. This memory is shared by all processes which use a certain library. Unfortunately there is no easy way to determine how much shared memory is used by how many processes. So a process can use 10Mb of shared memory, but you don't know whether this memory is shared with 1, 2 or 10 processes. So if you have 10 processes who each use 10Mb of shared memory this actually requires 10Mb in the best case and 100Mb in the worst case.

Code segments contain the actual executable code of your program. This memory is shared by all processes of this same program. If you start your program 5 times, it needs to load the code segment of your program only once.

Data segments contain the data of your program. This kind of memory is very important because the data segments of a process are not shared with other processes. Starting the same program 5 times makes that the data segments are 5 times in memory.

The size reported by ps auxf is typically just the numbers for shared, code and data added. This is not a very accurate representation of the memory usage of an application.

KDE applications tend to be reported as quite large because the numbers reported include the size of the shared memory segments. This size is added to the size of each KDE application while in practice the shared memory segments appear in memory only once. This is rather illusive, imagine how the output of ps would look like if it included the size of the UNIX kernel for each process!

Instead of looking at the output of ps you get a better idea of the actual memory usage of an application by looking at the output of

cat /proc/<pid-of-process>/status.

Example program

To demonstrate this, let's write a memory leaking program:

main.cpp

#include <KAboutData>
#include <KApplication>
#include <KCmdLineArgs>
#include <KMessageBox>

int main (int argc, char *argv[])
{
    KAboutData aboutData( "tutorial1", 0, ki18n("Tutorial 1"), "1.0",
                          ki18n("Displays a KMessageBox popup") );
 
    KCmdLineArgs::init( argc, argv, &aboutData );
    KApplication app;

    for ( int i=0; i<100000; i++ ) new QString();

    KMessageBox::questionYesNo( 0, i18n( "Hello World" ) );
    int* i;
    return 0;
}

CMakeLists.txt

project (tutorial1)
find_package(KDE4 REQUIRED)
include (KDE4Defaults)
include_directories(${KDE4_INCLUDES})
set(tutorial1_SRCS main.cpp)
kde4_add_executable(tutorial1 ${tutorial1_SRCS})
target_link_libraries(tutorial1 ${KDE4_KDEUI_LIBS})
install(TARGETS tutorial1  ${INSTALL_TARGETS_DEFAULT_ARGS})

Compile and linkthis program:

cmake . && make -j4

Run it:

./tutorial1 &
[3] 22733

In this case the program gets the process ID 22733. We look at its memory consumption:

cat /proc/22733/status
VmRSS:     19772 kB
VmData:     5776 kB
VmStk:        84 kB
VmExe:         8 kB
VmLib:     26804 kB

If we change the "100000" in the program code to "1", we get a different picture:

VmRSS:     16624 kB
VmData:     2652 kB
VmStk:        84 kB
VmExe:         8 kB
VmLib:     26804 kB

So we see the heap is counted to VmData and contained in VmRSS.

Further Information

More information about this topic can be found in the article about memory usage analysis.