LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (http://www.linuxquestions.org/questions/programming-9/)
-   -   how to programmatically monitor a process memory usage? (http://www.linuxquestions.org/questions/programming-9/how-to-programmatically-monitor-a-process-memory-usage-383517/)

thanhvn 11-15-2005 07:53 PM

how to programmatically monitor a process memory usage?
 
I need to obtain the memory usage (real and virtual) of a particular process every couple of seconds and write it to a log file. I'm thinking of writing either shell script (sh or bash) or a C/C++ program. What shell commands and/or C/C++ API's are available for this task?

Thanks,

twantrd 11-15-2005 10:13 PM

'bash' and 'ps' can do this:

Code:

twantrd:~# ps -o pid,vsz,rss,pmem,time,comm
  PID  VSZ  RSS %MEM    TIME COMMAND
  990  2580 1448  0.3 00:00:00 bash
 1205  1768  988  0.2 00:00:00 man
 1210  2272 1000  0.2 00:00:00 sh
 1214  1836  660  0.1 00:00:00 pager
 1281  2288  680  0.1 00:00:00 ps

This displays more than what you have asked, just giving you an idea. You can use this and pipe a grep to search for the process that you want. To capture this every couple of seconds, I would put this in an infinite while loop and sleep for X seconds and run the command.

-twantrd

primo 11-15-2005 10:52 PM

ps uses values from /proc/<pid>/stat

thanhvn 11-16-2005 02:45 AM

I am wondering:

1) how to get this GetMemUsage script and the program it monitors to start up at the same time? I don't want to start up the program then open a second console (the program writes to stdout) to launch the script. This means I would miss the first second or two of the program.

2) how to get this GetMemUsage script to shut down cleanly and automatically when the program it monitors shutdowns, even it shuts down abnormally? I would like the ability to batch run the program several times.

Thanks,

thanhvn 11-16-2005 02:54 AM

Also, how to get the elapsed time since the program started (preferrably in milliseconds or better resolution)? other than saving the start time and subtract it from the current time? what if I wanted CPU time and not wall-clock time?

Thanks,

thanhvn 11-21-2005 04:13 PM

Here's what I've got so far. This is the GetMemUsage script:

Code:

#!/bin/sh

USAGE="Usage: $0 processName"

if [ $# -ne 1 ]; then
  echo $USAGE
  exit 1
fi

# In case the monitored process has not yet started
# keep searching until its PID is found
PROCESS_PID=""
while :       
do
  PROCESS_PID=`/sbin/pidof $1`

  if [ "$PROCESS_PID.X" != ".X" ]; then
      break
  fi
done

LOG_FILE="memusage.csv"

echo "ElapsedTime,VmSize,VmRSS" > $LOG_FILE

ELAPSED_TIME=0
PERIOD=2        # seconds

# Monitor memory usage forever until script is killed
while :       
do
  VM_SIZE=`awk '/VmSize/ {print $2}' < /proc/$PROCESS_PID/status`
  if [ "$VM_SIZE.X" = ".X" ]; then
      continue
  fi
  VM_RSS=`awk '/VmRSS/ {print $2}' < /proc/$PROCESS_PID/status`
  if [ "$VM_RSS.X" = ".X" ]; then
      continue
  fi
  echo "$ELAPSED_TIME,$VM_SIZE,$VM_RSS" >> $LOG_FILE
  sleep $PERIOD
  VM_SIZE=""
  VM_RSS=""
  # Needs to get actual elapsed time instead of doing this
  ELAPSED_TIME=`expr $ELAPSED_TIME + $PERIOD`
done

Anyone knows how to get the actual elapsed time of a process (preferrably in milliseconds resolution but seconds resolution is fine)?

I cannot think of any way to have the GetMemUsage script launches and shuts down in synchronization with the monitored process other than to have a launch script that launches and shuts down both processes. Here's the launch script:

Code:

#!/bin/sh

Cleanup() {
  kill -9 `/sbin/pidof hello.out`
  kill -9 `ps ux | awk '/GetMemUsage.sh/ {print $2}'`
  exit $1
}
trap 'Cleanup 1' 1 2 3 15
./GetMemUsage.sh hello.out 2>&1 > /dev/null &
./hello.out
Cleanup 0

I realized this is not the most elegant way of doing it. Any suggestions for improvements are more than welcome.

ptobra 07-12-2007 07:43 AM

Monitoring the memory consumption of a process
 
How do i capture the memory usage of that particular process running in multiple threads. In linux every thread is displayed in the top statistics.
In solaris, the case is different it shows the number of threads as NLWP but one process.

Any clues. Can we do it using ps but if it list the /proc/pid/status

How can I get the memory consumption of a process in such case. Any ideas and suggestions.

Thanks in advance

ta0kira 07-12-2007 07:08 PM

Have you looked at man proc? That has a lot of info regarding how to interpret files in /proc/pid. I think everything you are looking for will be in /proc.

Are you talking about computer shutdown, or program exit when the monitored program exits?
ta0kira

chrism01 07-13-2007 12:46 AM

ptobra, what Linux kernel are you using.?
I did some dev in Perl thrs and found that 2.4.x Linux kernels show each thr as a separate process, but 2.6.x kernel shows only 1 process.
iirc, it's due to a change in the underlying kernel code.

ta0kira 07-13-2007 05:50 AM

Quote:

Originally Posted by chrism01
ptobra, what Linux kernel are you using.?
I did some dev in Perl thrs and found that 2.4.x Linux kernels show each thr as a separate process, but 2.6.x kernel shows only 1 process.
iirc, it's due to a change in the underlying kernel code.

Threads are shown under /proc/#/task in 2.6 and have most of the same info available as the main process.
ta0kira

ptobra 07-15-2007 02:49 AM

yes chris, you are right,
I am using Kernel 2.5.x only. I am still searching for a good solution.

Taokira, my problem is the same as chris mentioned. Every thread is shown as a process, so which pid should i use for capturing memory details.

Thanks
ptobra

chrism01 07-15-2007 08:42 PM

If the mem is shared between thrs (it might be/ can't remember), then choose the main/parent thr.
Otherwise, you'd have to sum all thrs mem values.
One way to check is to run a test on a quiet system, and observe the top values when prog is running vs not running.
Incidentally, iirc, only even-num (2.4, 2.6) kernels are prod ready, odd nums (2.5, 2.7) are dev/test ???

ptobra 07-15-2007 11:42 PM

I think getting the pid of parent thread and observing is most appropriate.
Summing up all thread mem values and the calculating the average also makes sense.

Thanks chris

chandan_maddanna 09-09-2007 10:18 AM

Hi Guys, i have got a bit better solution
 
Hey All,

We can use smap to get accurate memory consumption , rather than using VMSIZE or RSS as above.

check these links out, i have just compiled.

Per process accurate memory usage , private region , public region and shared library page mapping included. better than VMSIZE and RSS values.

http://unixlive.editboard.com/Genera...ral-p14.htm#14

How much RAM / Memory does a program use. Note that this takes care of parent process etc, mentioned above, and gives usage for a program ( not a process ). so this is really helpful.


http://unixlive.editboard.com/Genera...program-t5.htm


Regards,

-- Chandan

Quote:

Originally Posted by ptobra (Post 2824777)
I think getting the pid of parent thread and observing is most appropriate.
Summing up all thread mem values and the calculating the average also makes sense.

Thanks chris


thinker0 02-20-2009 01:15 AM

MultiThread process... patch

Code:

#!/bin/sh

USAGE="Usage: $0 processName"

if [ $# -ne 1 ]; then
  echo $USAGE
  exit 1
fi


LOG_FILE="memusage.csv"

echo "ElapsedTime,VmSize,VmRSS" > $LOG_FILE

ELAPSED_TIME=0
PERIOD=1        # seconds

# Monitor memory usage forever until script is killed
while :
do
  SUM_VM_SIZE=0
  SUM_RSS_SIZE=0
  # In case the monitored process has not yet started
  # keep searching until its PID is found
  PROCESS_PIDS=""
  while :
  do
      PROCESS_PIDS=`/sbin/pidof $1`

      if [ "$PROCESS_PIDS.X" != ".X" ]; then
        break
      fi
  done

  for PID in ${PROCESS_PIDS} ; do
    VM_SIZE=`awk '/VmSize/ {print $2}' < /proc/$PID/status`
    if [ "$VM_SIZE.X" = ".X" ]; then
        continue
    fi
    #echo exprVM_ $SUM_VM_SIZE + $VM_SIZE
    SUM_VM_SIZE=`expr $SUM_VM_SIZE + $VM_SIZE`

    VM_RSS=`awk '/VmRSS/ {print $2}' < /proc/$PID/status`
    if [ "$VM_RSS.X" = ".X" ]; then
        continue
    fi
    SUM_RSS_SIZE=`expr $SUM_RSS_SIZE + $VM_RSS`
  done
  echo "$ELAPSED_TIME sec, $SUM_VM_SIZE KB, $SUM_RSS_SIZE KB"
  echo "$ELAPSED_TIME,$SUM_VM_SIZE,$SUM_RSS_SIZE" >> $LOG_FILE
  sleep $PERIOD
  VM_SIZE=""
  VM_RSS=""
  # Needs to get actual elapsed time instead of doing this
  ELAPSED_TIME=`expr $ELAPSED_TIME + $PERIOD`
done



All times are GMT -5. The time now is 04:38 AM.