Memory consumption: scratching the surface

On Linux platform, WebKit doesn't provide us with tools/scripts for investigating memory consumption, although this topic might be almost as important as runtime performance. For example, just think of an embedded environment where memory is limited and the usage of memory has an impact on the device's power consumption.

Fortunately, Linux's 2.6.16 kernel adds support for smaps, thus we are able to retrive useful information about processes' and libraries' RSS (resident set size). In our investigations we used the following hardware and software setup:

  • VMware with Debian-Etch x86
  • 1 single core CPU
  • 2 GB RAM (and swap was turned off)
  • WebKit's Linux-Qt port
  • Qt-4.5.1
  • WebKit revision r43208
  • JIT was enabled

We classified the mapped memory areas into 5 categories:

  • WebKit (blue): includes the areas that have been mapped for the QtWebKit library (.code and .data segment's size)
  • Qt (green): includes the memory consumption of Qt libraries (.code and .data segment's size)
  • Other (orange): includes all other libs used by the system (.code and .data segment's size)
  • Stack: the stack size of the actual process(es)
  • Heap: the heap size of the actual process(es)

QtLauncher with no content

Frist, let's see how QtLauncher fits in the memory right after the start, without loading a page.

So, now we have some idea of a single QtLauncher's memory map. Let's continue our investigation with some interesting measurements.

On the next diagram, again I compared QtLauncher's memory consumption after the start, without content load. However, I varied the number of executed processes and opened tabs. The first coloumn in the chart below demonstrates the setup used for the previous diagram (1 process 1 window), the second and third coloumns demonstrate the memory consumption of QtLaunchers that I started in one process with two tabs (1 process 2 tabs) and in two separate processes (2 processes 2 windows).

QtLauncher with Benchmarks

1 process running

Now, let's see the memory consumption of runtime benchmarks (SunSpider, V8, WindScorpion). As you can see our WindScorpion benchmark has the longest runtime and also has the highest memory consumption. SunSpider takes half the time to finish, with less memory consumption and V8 runs quarter of the time and its memory consumption is similar to SunSpider's. (The horizontal axis represents the elapsed time in seconds and the vertical axis represents the memory consumption in kilobytes.)

2 processes versus 1 process running

Now let's see the comparison of simultaneously runnig benchmarks in 2 processes (with 1 window each) and in 1 process with 2 tabs. As you can see for SunSpider, the running time is similar for both cases, but the memory consumption is higher with the two processes setup (as we would expect):

Interestingly, the maximum memory consumption of the V8 benchmark is similar for the 2 processes 1-1 window and for the 1 processes 2 tabs setup.

The WindScorpion benchmark breaks the trend in this case, because it runs much faster with two processes, than with one process. The maximum memory consumption is almost the same.

3 processes versus 1 process running

In the last test, let's see what happens when the three WebKit benchmarks run simultaneously in 3 processes (3 windows) and in 1 process (3 tabs):

In this case, both the running time and the memory consumption is different for the 3 processes 3 windows and the 1 process 3 tabs setup.

Conclusions?

We got a bit of insight into the memory consumption of QtLauncher under load, during stress tests. However, the findings bring up additional questions that would be worthy of examination in the future.

  • After all, is it worthwhile to run each JavaScript / WebPage / Tab in its own process?
  • If we go for a process-level isolation, would it be possible to share the multiple process heaps? Would it useful? Won't it decrease the runtime performance?

zoltan.horvath - 05/19/2009 - 11:50

There was a mistake in the 2nd figure's 2nd column. I corrected the columns. Thanks for the notice. Feel free to ask.

LKRaider (not verified) - 06/16/2009 - 21:21

How do you get 4mb on webkit only? I'm using QtEmbedded (git clone of master), and smaps shows ~20mb for libQtWebKit:

29580000-2b31a000 r-xp 00000000 00:0d 3704693 /mnt/usr/local/QtEmbedded/lib/libQtWebKit.so.4.6.0
Size: 30312 kB
Rss: 20236 kB
Shared_Clean: 0 kB
Shared_Dirty: 0 kB
Private_Clean: 20236 kB
Private_Dirty: 0 kB
Referenced: 20236 kB

This is on an app that only instanciates a QWebView that loads google's frontpage.

foo (not verified) - 07/06/2010 - 15:50

As LKRaider pointed out, I wonder how you get a libQtWebKit.so of ~4MB...

zoltan.horvath - 07/07/2010 - 08:32

I checked it now and on my machine it shows only ~7MB.

foo (not verified) - 07/07/2010 - 16:08

Still far from my 23, 24MB!! How can you reach such a small values ? Thank for any hints

Using Qt 4.6.3
WebKit r62477

WebKit$ WebKitTools/Scripts/build-webkit --qt --no-video --no-sandbox --no-ruby

[...]

WebKit$ ls -lh WebKitBuild/Release/lib/libQtWebKit.*
-rw-r--r-- 1 foo foo 514 2o010-07-07 16:49 WebKitBuild/Release/lib/libQtWebKit.prl
lrwxrwxrwx 1 foo foo 20 2010-07-07 16:36 WebKitBuild/Release/lib/libQtWebKit.so -> libQtWebKit.so.4.8.0
lrwxrwxrwx 1 foo foo 20 2010-07-07 16:36 WebKitBuild/Release/lib/libQtWebKit.so.4 -> libQtWebKit.so.4.8.0
lrwxrwxrwx 1 foo foo 20 2010-07-07 16:36 WebKitBuild/Release/lib/libQtWebKit.so.4.8 -> libQtWebKit.so.4.8.0
-rwxr-xr-x 1 foo foo 23M 2010-07-07 16:36 WebKitBuild/Release/lib/libQtWebKit.so.4.8.0

zoltan.horvath - 07/07/2010 - 16:14

hey,

libQtWebKit.so's size is 24MB for me also.
The mapped memory for it is much smaller. The system doesn't load the entire .so into the memory.
Check the process' smaps file!

Zoltan

foo (not verified) - 07/07/2010 - 20:12

That's a good point :P Sorry, my fault.

I will do some tests. I wonder what's inside of the remaining 20MB of the shared lib...

thanks for the ready feedback!

Anonymous (not verified) - 07/08/2010 - 09:00

Ok, here an excerpt from smaps

[cut]
b6db6000-b7f62000 r-xp 00000000 08:03 1917804 /home/alberto/WebKit/WebKitBuild/Release/lib/libQtWebKit.so.4.8.0
Size: 18096 kB
Rss: 3992 kB
Pss: 3992 kB
Shared_Clean: 0 kB
Shared_Dirty: 0 kB
Private_Clean: 3992 kB
Private_Dirty: 0 kB
Referenced: 3992 kB
Swap: 0 kB
[cut]

Hoping in your patience, I will ask another question. Supposing QtTestBrowser is the only application
on my system using QtWebKit, the remaining 18096 kB that are not mapped are in physical RAM ?
I thought that when the linker loads a binary bound with a shared library, the whole shared library was
loaded, despite that there are only mapping to some parts of the library...

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • No HTML tags allowed
  • Lines and paragraphs break automatically.

More information about formatting options

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
Fill in the blank