Less known Solaris Features: Resource Management - Part 5: Management of memory resources

So far we configured limits on the usage of operating syste resources and the CPU. Let´s get back to the class room example used before. A different course at the unseen university is “Memory Management for beginners”. And at start our students have problem with severe memory leaks. It would be useful to impose resource management to the memory management.  

Without Resource Management

Bob wrote a little script within Perl that eats a large amount of the available memory.

#!/usr/bin/perl<br />
for ($i=0;$i<10;$i++) {<br />
 push @_,"x"x(1*1024*1024);<br />
 sleep(5);<br />
}<br />
sleep(30);<br />
for ($i=0;$i<10;$i++) {<br />
 push @_,"x"x(1*1024*1024);<br />
 sleep(5);<br />
}

When we start this script, it will allocate memory by pushing blocks of 1 Megabyte of x chars onto a stack.

# ps -ef -o pid,user,vsz,rss,project,args | grep "bob" | grep -v "grep"<br />
 1015      bob 8728  892 class2005 /usr/lib/ssh/sshd<br />
 1362      bob 26148 24256 class2005 /usr/bin/perl ./memoryhog.pl<br />
 1016      bob 1624  184 class2005 -sh<br />
 1031      bob 3260 1336 class2005 bash

When you look in the forth column you see the resident set size. The resident set is the amout of data of a process in the real memory. After a short moment the process ./memoryhog.pl uses 24 MB of our precious memory (20 times 1 MB plus the perl interpreter minus some shared stuff).

Memory resource management

It would be nice to control the amount of data, that resides in the real memory. Solaris has such a capability. At first we have to activate the resource cap enforcement daemon. You have to login as root to do so:

# rcapadm -E

The rcapd daemon enforces resource caps on a group of processes. The rcapd supports caps on projects and zones at the moment. When the resident set size of a group of processes exceeds the defined cap. To reduce the resource consumption of a process group, the daemon can page out infrequently uses pages of memory to swap. For testing purposes we configure the daemon in such a way, that it scans every second for new processes in projects with a resource cap. Furthermore we configure it to sample the resident set size every 1 second, too. Additionally the pageout statistics of the rcapd will be updated every second, too.

# rcapadm -i scan=1,sample=1,report=1

For testing purposes we define a new project called mmgntcourse and add the user bob to this project:

# projadd mmgntcourse<br />
# projmod -U bob mmgntcourse

Now we set an resource cap for the resident set size of 5 Megabytes for this project:

# projmod -K rcap.max-rss=5242880 mmgntcourse

Okay, now get back to the window with the login of user bob. Let´s start the memoryhog.pl in the mmgntcourse:

$ newtask -p mmgntcourse ./memoryhog.pl

Okay, get back to a different window and login as root. With the rcapstat you can observe the activities of the rcapd. In our example we tell rcapstat to print the statistics every 5 seconds:

# rcapstat 5<br />
    id project         nproc    vm   rss   cap    at avgat    pg avgpg<br />
   105 mmgntcourse         - 2352K 3876K 5120K    0K    0K    0K    0K<br />
   105 mmgntcourse         - 3376K 4900K 5120K    0K    0K    0K    0K<br />
   105 mmgntcourse         1 4400K 5924K 5120K  812K  812K  804K  804K<br />
   105 mmgntcourse         1 5424K 6408K 5120K 3380K 1126K 3380K 1126K<br />
   105 mmgntcourse         - 6448K 4856K 5120K    0K    0K    0K    0K<br />
   105 mmgntcourse         1 7472K 5880K 5120K  760K  760K  760K  760K<br />
   105 mmgntcourse         1 8496K 5384K 5120K 1024K  512K 1024K  512K<br />
   105 mmgntcourse         1 9520K 6144K 5120K 1024K 1024K 1024K 1024K<br />
   105 mmgntcourse         1   10M 5120K 5120K 1024K 1024K 1024K 1024K<br />
   105 mmgntcourse         1   11M 6144K 5120K 1024K 1024K 1024K 1024K<br />
   105 mmgntcourse         1   11M 4096K 5120K 1024K 1024K 1024K 1024K<br />
   105 mmgntcourse         -   11M 4096K 5120K    0K    0K    0K    0K<br />
[...]<br />
   105 mmgntcourse         -   11M 4096K 5120K    0K    0K    0K    0K<br />
   105 mmgntcourse         1   14M 5892K 5120K 2820K  940K 2820K  940K<br />
   105 mmgntcourse         1   15M 5628K 5120K 1280K  640K 1280K  640K<br />
   105 mmgntcourse         1   16M 6144K 5120K 1024K 1024K 1024K 1024K<br />
   105 mmgntcourse         1   17M 6144K 5120K 1024K 1024K 1024K 1024K<br />
   105 mmgntcourse         1   18M 5120K 5120K 1024K 1024K 1024K 1024K<br />
   105 mmgntcourse         -   18M 5120K 5120K    0K    0K    0K    0K<br />
   105 mmgntcourse         1   20M 5120K 5120K 2048K 1024K 2048K 1024K<br />
   105 mmgntcourse         -   20M 5120K 5120K    0K    0K    0K    0K<br />
   105 mmgntcourse         1   22M 5120K 5120K 2048K 1024K 2048K 1024K

As you see, the resident set size stays at approx. 5 Megabyte. The RSS may increase above the configured size, as the applications may allocate memory between the RSS sampling intervals. But at the next sampling size the rcap starts to force the page out of this exceeding pages. After a few seconds the resident set size is enforced, again. You can observe this behaviour in column 5 of the rcapstat printout.