How do you record how much memory an app is using on OS X

0

I'm on a Mac Mini with OS X 10.8.2. I am an app developer, but in this case am building an app in C++, so I can not use Xcode for this question. I would like to track how much memory my app is using, but I don't want to manually record it. How do I do this.

MORE INFO: I want to record it all day long. I will have the app running all day, so that I can compare peaks in memory. I am not opposed to 3rd party apps, as long as they are reliable. Thanks.

Josiah

Posted 2012-12-03T16:52:28.247

Reputation: 1 674

Not really a programmer, but Valgrind maybe?

– slhck – 2012-12-03T16:57:43.170

You can use the Instruments app by attaching to any process without firing up Xcode itself. – Ken – 2012-12-03T18:03:30.417

I did see that. However I saw no way to "go back in time" and view the memory throughout the day. If you could explain how to use/read it. That would be fine. – Josiah – 2012-12-03T18:14:55.393

Answers

3

You should be able to do this using the standard ps command. From man ps:

%mem        %MEM      ratio of the process's resident set size  to the physical
                      memory on the machine, expressed as a percentage.  

rss         RSS       resident set size, the non-swapped physical memory that 
                      a task has used (inkiloBytes). 

vsz         VSZ       virtual memory size of the process in KiB (1024byte units).
                      Device mappings are currently excluded; this is subject
                      to change. 

The only other detail you need is your process' PID. So, if your app is called myApp, you can get the PID like this:

ps x | grep myApp

Which prints a list like this:

15909 pts/3    S      0:37 myApp
22583 pts/6    S+     0:00 grep --color myApp

The first column is the process ID (PID). Now, if you want to automate this, you need to skip the line containing the grep command and save the output in a BASH variable:

pid=$(ps x | grep myApp | grep -v grep | awk '{print $1}')

The awk part makes the command print only the 1st field, the PID.


You can put all this together into a one liner that will save the memory usage of your app every minute into a file called memlog.txt:

while sleep 60; do \
    pid=$(ps x | grep myApp | grep -v grep | awk '{print $1}') && \
    ps xo pid,rss,vsz,%mem | grep "$pid" >> memlog.txt ; \
done 
  • while sleep 60 causes bash to run in an infinite loop, waiting 60secs between loops
  • sleep 60 tells it to wait for 60 seconds. Change this value if you need it to update more often.

The resulting output is a file (memlog.txt) with 4 columns: your app's PID, the resident set size, the virtual memory size and the memory percentage. For example:

4166 25240 633028  0.3
4166 25240 633028  0.3
4166 25240 633028  0.3

This can easily be extended to include cpu usage and a time for each measurement. For example, to include time:

while sleep 60; do \
    date=$(date +%D" "%H:%M:%S);
    echo -n "$date : " >> memlog.txt;
    pid=$(ps x | grep myApp | grep -v grep | awk '{print $1}') && \
    ps xo pid,rss,vsz,%mem | grep "$pid" >> memlog.txt; \
done 

terdon

Posted 2012-12-03T16:52:28.247

Reputation: 45 216

I get an error on the first line. I don't think while(1); do \ is correct. Please correct that. Also, if this does work, I would really prefer something a little more visual. It doesn't seem like this should be hard to do. – Josiah – 2012-12-03T18:11:50.530

Really I would like something like Instruments.app, or perhaps that exact tool. However, even though it does record memory, it doesn't seem to keep track of a specific application's memory. – Josiah – 2012-12-03T18:12:47.237

@AceLegend, the \`` is just to tell BASH that the command continues in the next line, used here for ease of reading. It should work if you just copy paste it directly, it wont if you copy it by hand. The entire thing in one line iswhile(1); do date=$(date +%D" "%H:%M:%S); echo -n "$date : " >> memlog.txt; pid=$(ps x | grep myApp | grep -v grep | gawk '{print $1}') && ps xo pid,rss,vsz,%mem | grep "$pid" >> memlog.txt; sleep 60 ; done`. As for visual, I would just take the values and plot them. – terdon – 2012-12-03T18:21:00.513

I understand, but it still doesn't work. I created a file with the line #!/bin/bash skipped a line, then: while(1); do date=$(date +%D" "%H:%M:%S); echo -n "$date : " >> memlog.txt; pid=$(ps x | grep Nightly | grep -v grep | gawk '{print $1}') && ps xo pid,rss,vsz,%mem | grep "$pid" >> memlog.txt; sleep 60 ; done – Josiah – 2012-12-03T18:30:57.947

I then saved it as memTesting.sh, and used sudo chmod +x to make it executable. Then ./memTesting.sh. It still throws an error saying that it is using an unknown command. – Josiah – 2012-12-03T18:32:14.700

OK, I found it, the problem is a difference in BASH between OSX and Linux. The command I gave you works fine on my linux box but OSX BASH does not like while(1). I have updated my answer, it should work now. I also changed gawk to awk just in case. I am not sure but I think that awk is installed by default on OSX. Let me know if not. – terdon – 2012-12-03T18:48:08.693