57

time is a brilliant command if you want to figure out how much CPU time a given command takes.

I am looking for something similar that can measure the max RAM usage of the program and any children. Preferably it should distinguish between allocated memory that was used and unused. Maybe it could even give the median memory usage (so the memory usage you should expect when running for a long time).

So I would like to do:

rammeassure my_program my_args

and get output similar to:

Max memory allocated: 10233303 Bytes
Max memory used: 7233303 Bytes
Median memory allocation: 5233303 Bytes

I have looked at memusg https://gist.github.com/526585/590293d6527c91e48fcb08edb8de9fd6c88a6d82 but I regard that as somewhat a hack.

5 Answers 5

41

time is a built-in of your shell. If you like time but need more information, try GNU time in verbose (-v) mode:

/usr/bin/time -v sleep 5               
    Command being timed: "sleep 5"
    User time (seconds): 0.00
    System time (seconds): 0.00
    Percent of CPU this job got: 0%
    Elapsed (wall clock) time (h:mm:ss or m:ss): 0:05.00
    Average shared text size (kbytes): 0
    Average unshared data size (kbytes): 0
    Average stack size (kbytes): 0
    Average total size (kbytes): 0
    Maximum resident set size (kbytes): 2144
    Average resident set size (kbytes): 0
    Major (requiring I/O) page faults: 0
    Minor (reclaiming a frame) page faults: 179
    Voluntary context switches: 2
    Involuntary context switches: 1
    Swaps: 0
    File system inputs: 0
    File system outputs: 0
    Socket messages sent: 0
    Socket messages received: 0
    Signals delivered: 0
    Page size (bytes): 4096
    Exit status: 0

Search the package "time" or "gnutime" in your package manager.

6
  • 3
    Note that some information reported by GNU time could be inaccurate. E.g. under Ubuntu 10.04: The man page states 'The numbers are only as good as those returned by wait3(2)'. I.e. wait3 fills a structure which is described in getrusage(2): 'Not all fields are meaningful under Linux. [..]'. Commented Aug 16, 2011 at 19:49
  • 5
    For example on a test program that exactly allocates 10 MB (and touches each page) - GNU time reports a maxRSS of 42608 KiB - and tstime reports 10652 KiB. Again under Ubuntu 10.04. Commented Aug 16, 2011 at 19:58
  • I would have loved if it was this simple. On my Ubuntu machine I tried: /usr/bin/time -v perl -e '$a="x"x100000000;$b=$a.$a;sleep 10;'. top says it takes around 570 MB, but time says 2.3 GB. In practice that number is not usuable to me.
    – Ole Tange
    Commented Aug 22, 2011 at 11:56
  • The factor of 4 is fixed in GNU time 1.7 and thus works as expected.
    – Ole Tange
    Commented Jan 30, 2013 at 13:16
  • 1
    Important note: The "Maximum resident set size" only works since Linux 2.6.32.
    – Jan Hudec
    Commented Nov 24, 2014 at 14:45
28

You can use tstime to measure the highwater memory usage (RSS and virtual) of a process.

For example:

$ tstime date       
Tue Aug 16 21:35:02 CEST 2011

Exit status: 0

pid: 31169 (date) started: Tue Aug 16 21:35:02 2011
        real   0.017 s, user   0.000 s, sys   0.000s
        rss      888 kb, vm     9764 kb

It also supports a more easy to parse output mode (-t).

7
  • I like it. It even did The Right Thing with ./tstime -t bash -c 'perl -e "\$a=\"x\"x100000000;\$b=\$a.\$a;\$b=\"\";\$a=\"\";sleep 10;"'
    – Ole Tange
    Commented Aug 22, 2011 at 12:00
  • 3
    "RAM usage by the process" isn't a well-defined value: If there are several instances of the same program running, they share the executable. Most programs share glibc (and other assorted libraries, they are called "shared" for something). Many daemons load configuration into memory and fork(2) children, who then share the configuration data. Then there is data in readahead/writebehind buffers managed by the kernel. And then there are services that are a herd of loosely coupled processes (think of your desktop environment and all its applets and background stuff).
    – vonbrand
    Commented Jan 23, 2013 at 16:05
  • @vonbrand, how the Linux-Kernel computes the RSS/VSS values is well-defined. Commented Jan 23, 2013 at 19:46
  • @maxschlepzig, it may well compute some random values, that doesn't mean they mean what you think they mean: The resident set is just the pages in the process' address space that are currently in memory. That is not the "memory used by this process", it includes whatever it is sharing.
    – vonbrand
    Commented Jan 23, 2013 at 19:50
  • @vonbrand Most use cases of measuring a process's memory usage will want to measure un-shared anonymous pages, which should be very predictable with the same input. Commented May 2, 2015 at 12:56
19

Maybe overkill, but I just found that valgrind has a nice tool named massif. I tested it on xterm:

valgrind --trace-children=yes --tool=massif xterm
ms_print massif.out.* | less

And you obtain a nice memory usage graph:

    MB
4.230^                     #                    :::::::  :::      @@:     ::: 
     |   @                 #:::@::@@:::::@::::::: :: : ::: :::::::@ ::::::: ::
     |   @               ::#:: @: @ ::: :@: :: :: :: : ::: ::: : :@ :: : :: ::
     |   @::::@@:::::::::: #:: @: @ ::: :@: :: :: :: : ::: ::: : :@ :: : :: ::
     |   @::: @ :: ::: : : #:: @: @ ::: :@: :: :: :: : ::: ::: : :@ :: : :: ::
     |   @::: @ :: ::: : : #:: @: @ ::: :@: :: :: :: : ::: ::: : :@ :: : :: ::
     |   @::: @ :: ::: : : #:: @: @ ::: :@: :: :: :: : ::: ::: : :@ :: : :: ::
     |   @::: @ :: ::: : : #:: @: @ ::: :@: :: :: :: : ::: ::: : :@ :: : :: ::
     |   @::: @ :: ::: : : #:: @: @ ::: :@: :: :: :: : ::: ::: : :@ :: : :: ::
     |   @::: @ :: ::: : : #:: @: @ ::: :@: :: :: :: : ::: ::: : :@ :: : :: ::
   0 +----------------------------------------------------------------------->Mi
     0                                                                   292.4

along with overly detailed memory usage info. Details in the valgrind manual.

Programs will run about 20x slower though. Also, I ran some commands inside the xterm. Their memory footprint has been taken into account because the --trace-children=yes the option is there!

2
  • 2
    Th 20x speed penalty makes it unsuable for my situation. Otherwise very pretty graph!
    – Ole Tange
    Commented Aug 22, 2011 at 11:59
  • 1
    It looks like that, at least in the version 3.8.1 of valgrind that I am using, booleans are only accepted in the form "yes/no" and not "true/false". Mine complained! :-)
    – MakisH
    Commented Feb 17, 2016 at 1:09
6

Even though the topic is quite old, I want to share another project that emerged from the cgroups Linux kernel feature.

https://github.com/gsauthof/cgmemtime:

cgmemtime measures the high-water RSS+CACHE memory usage of a process and its descendant processes.

To be able to do so it puts the process into its own cgroup.

For example process A allocates 10 MiB and forks a child B that allocates 20 MiB and that forks a child C that allocates 30 MiB. All three processes share a time window where their allocations result in corresponding RSS (resident set size) memory usage.

The question now is: How much memory is actually used as a result of running A?

Answer: 60 MiB

cgmemtime is the tool to answer such questions.

3

Looks like tstime doesn't work anymore under non-root under Linux >=3.0. Here's a polling utility I wrote to hack around the issue: https://github.com/jhclark/memusg/blob/master/memusg

2
  • 1
    /usr/bin/time -v gives the correct output in newer versions. In older versions you just need to divide by 4 to get the correct amount.
    – Ole Tange
    Commented Aug 30, 2012 at 22:42
  • However, I don't think time -v supports peak vmemory size (only RSS). Can anyone confirm this on the latest version?
    – jhclark
    Commented Sep 1, 2012 at 0:48

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .