[prev in list] [next in list] [prev in thread] [next in thread] 

List:       hpux-devtools
Subject:    Re: HPUX-DEVTOOLS: Get the total memory of a process
From:       Mike Stroyan <stroyan () hpstryn ! fc ! hp ! com>
Date:       2002-11-07 0:58:55
[Download RAW message or body]

On Wed, Nov 06, 2002 at 03:09:27PM -0600, Wesley.Ren@nokia.com wrote:
> I need to get the total memory used by a process. I know I can use
> pstat_getprocvm() to get back a pst-vm_status. But the fields in the data
> structure is not a clear at all. I search documentation but I coulnd't find
> too much help. Could anybody please tell me the meaning of each field in the
> data structure?
> I have read some examples that get the total virtual memory by adding up
> pst_length and total private memory by adding up pst_phys_pages. But then the
> examples assumed the page size for both virtual memory and private memory as
> 4k. But in HP 11, there is a pst_vps_pgsizes field in pst_vm_status. Should we
> get page size from pst_vps_pgsizes or assume it as 4k?

  In general, data fields that count in "pages" are using 4KB pages,
also known as sysconf(_SC_PAGE_SIZE).  The only fields from
pstat_getprocvm() that know anything about variable page sizes are the
pst_vps_pgsizes and pst_pagesize_hint fields.  Other fields like
pst_length and pst_phys_pages continue to report in terms of the same
small page size that they always used.  The pstat_getstatic() call
reports some data about supported page sizes.  The pstat_getvminfo()
call reports some summary data about the ability to allocate large
pages.

  The interesting fields for counting memory use are pst_phys_pages
and pst_length.  The pst_phys_pages shows how much RAM a segment is
currently occupying.  The pst_length shows the size of the segments
valid address range.  Many segments reserver enough swap to back up
their entire address range.  Segments don't need swap if they memory
map a file.  Segments with the lazy-swap attribute set will only
allocate swap for pages that have been referenced.

  One of the trickiest parts of counting memory use is deciding how to
account for shared memory segments.  Do you bill every mapping process
for a complete shared memory segment, or divide evenly among the
processes, or ignore the shared memory completely?  That is up to you.

-- 
Mike Stroyan, mike_stroyan@hp.com

P.S.  Here is yet another example that counts sizes.  It divides
      the size of shared memory regions by their reference count.


# This is a shell archive.  Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Wrapped by Mike Stroyan <stroyan@hpstryn> on Wed Nov  6 17:57:08 2002
#
# This archive contains:
#	procvm_sizes_glance.c	
#

LANG=""; export LANG
PATH=/bin:/usr/bin:/usr/sbin:/usr/ccs/bin:$PATH; export PATH

echo x - procvm_sizes_glance.c
cat >procvm_sizes_glance.c <<'@EOF'
#define _PSTAT64
#include <sys/param.h>
#include <sys/pstat.h>
#include <sys/unistd.h>
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>

typedef struct shared_segment_struct {
    long long pst_space;
    long long pst_vaddr;
    int refs;
    struct shared_segment_struct *next;
} segment;

static segment *shared_segs = NULL;

void pstatvm(int pid)
{
    struct pst_vm_status pst;
    int idx, count;
    long long shared_vm = 0;
    long long shared_ram = 0;
    long long private_vm = 0;
    long long private_ram = 0;

    idx=0;
    count = pstat_getprocvm(&pst, sizeof(pst), (size_t)pid, idx);
    while (count > 0) {
	switch ((long)pst.pst_type) {
	    case PS_IO: break;
		/* Don't count IO space.  It really is not RAM or swap. */
	    default: 
		if (pst.pst_flags & PS_SHARED) {
		    segment *s;
		    int refs = 1;
		    for (s=shared_segs; s; s=s->next) {
			if (s->pst_space == pst.pst_space
			&& s->pst_vaddr == pst.pst_vaddr) {
			    refs = s->refs;
			    break;
			}
		    }
		    shared_vm += (long long) pst.pst_length;
		    shared_ram += (long long)pst.pst_phys_pages/refs;
		} else {
		    private_vm += (long long) pst.pst_length;
		    private_ram += (long long)pst.pst_phys_pages;
		}
		break;
	}

	idx++;
	count = pstat_getprocvm(&pst, sizeof(pst), (size_t)pid, idx);
    }
    printf("%6d ", pid);
    printf("%11lldK ", shared_vm*4);
    printf("%11lldK ", shared_ram*4);
    printf("%11lldK ", private_vm*4);
    printf("%11lldK ", private_ram*4);
    printf("%11.1fM\n", (shared_ram+private_ram)/256.0);
}

void pstatvm_all(void)
{
#define BURST ((size_t)10)

    struct pst_status pst[BURST];
    int i, count;
    int idx = 0; /* index within the context */

    /* loop until count == 0, will occur when all have been returned */
    while ((count = pstat_getproc(pst, sizeof(pst[0]), BURST, idx)) > 0)
    {
	/* got count (max of BURST) this time.  process them */
	for (i = 0; i < count; i++) {
	    if (pst[i].pst_pid==0) continue; /* Can't getprocvm real pid 0 */
	    pstatvm(pst[i].pst_pid);
	}

	/*
	 * now go back and do it again, using the next index after
	 * the current 'burst'
	 */
	idx = pst[count-1].pst_idx + 1;
    }

    if (count == -1)
	perror("pstat_getproc()");

#undef BURST
}

void pstat_refcount_all(void)
{
#define BURST ((size_t)10)

    struct pst_status pst[BURST];
    int i, count;
    int idx = 0; /* index within the context */

    /* loop until count == 0, will occur when all have been returned */
    while ((count = pstat_getproc(pst, sizeof(pst[0]), BURST, idx)) > 0)
    {
	/* got count (max of BURST) this time.  process them */
	for (i = 0; i < count; i++) {
	    struct pst_vm_status vm;
	    int reg, count;

	    if (pst[i].pst_pid==0) continue; /* Can't getprocvm real pid 0 */
	    reg=0;
	    while (pstat_getprocvm(&vm, sizeof(vm), pst[i].pst_pid, reg++)) {
		segment *s;
		for (s=shared_segs; s; s=s->next) {
		    if (s->pst_space == vm.pst_space
		    && s->pst_vaddr == vm.pst_vaddr) {
			s->refs += 1;
			break;
		    }
		}
		if (!s) {
		    s = malloc(sizeof(segment));
		    s->pst_space = vm.pst_space;
		    s->pst_vaddr = vm.pst_vaddr;
		    s->refs = 1;
		    s->next = shared_segs;
		    shared_segs = s;
		}
		reg++;
	    }
	}
	idx = pst[count-1].pst_idx + 1;
    }

    if (count == -1)
	perror("pstat_getproc()");

#undef BURST
}

main(int argc, char *argv[])
{
    int i;
    pstat_refcount_all();
    printf("   pid    shared_vm   shared_ram   private_vm  private_ram      Res_Mem\n");
    if (argc > 1) {
	for (i=1; i<argc; i++)
	    pstatvm(atoi(argv[i]));
    } else {
	pstatvm_all();
    }
}
@EOF

chmod 664 procvm_sizes_glance.c

exit 0
 _________________________________________________________________
 To leave this mailing list, send mail to majordomo@cxx.cup.hp.com
    with the message UNSUBSCRIBE hpux-devtools
 _________________________________________________________________
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic