• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 337
  • Last Modified:

Pages allocated to a process

How do i determine the no pages allocated to process , knowing the pid of the process ,
0
mmadhuso
Asked:
mmadhuso
  • 9
  • 8
1 Solution
 
jkrCommented:
Use 'GetProcessWorkingSetSize()' (http://windowssdk.msdn.microsoft.com/library/en-us/dllproc/base/getprocessworkingsetsize.asp), e.g.

HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,dwProcessId);

DWORD dwMin;
DWORD dwMax;

GetProcessWorkingSetSize(hProcess,&dwMin,&dwMax);

From the docs:

The "working set" of a process is the set of memory pages currently visible to the process in physical RAM memory. These pages are resident and available for an application to use without triggering a page fault. The size of a process' working set is specified in bytes. The minimum and maximum working set sizes affect the virtual memory paging behavior of a process.
0
 
mmadhusoAuthor Commented:
Thanks for the help

But i want the no of pages , i mean the number of pages allocated at instance of time ,

    getworkingsetsize() gives the min and max values ,

 i need to access each page of the process taht is in the memory
0
 
Mikeh926Commented:
Hi,
The api you are looking foris VirtualQueryEx(). Starting at address zero you can enumerate all of the memory blocks in the processes address space to determine if they are allocated, commited or free. You can then add up the total number of commited pages in use by the process.

Regards,
Mike.
0
Cloud Class® Course: Microsoft Office 2010

This course will introduce you to the interfaces and features of Microsoft Office 2010 Word, Excel, PowerPoint, Outlook, and Access. You will learn about the features that are shared between all products in the Office suite, as well as the new features that are product specific.

 
mmadhusoAuthor Commented:
Hi Mike
Thanks for the help

but  i am bit worried about what do i need to do with  
LPCVOID lpAddress, the 2 nd paramenter of VirtualQueryEx() ,,,

can you just help me in giving some code snippet of this written in  c or c++ as
i am struck in a dead lock

thanks
0
 
Mikeh926Commented:
HANDLE proc = OpenProcess(PROCESS_ALL_ACCESS,TRUE,GetCurrentProcessId());

if (proc)
      {
      char buf[120];
      DWORD address = 0;
      MEMORY_BASIC_INFORMATION mbi;

      while(address<0x7fffffff)      // std 2GB offset btwn User and Kernel memory - might need to
                                                // get this programatically as it can change to 3GB on some OS's.
            {
            VirtualQueryEx(proc,(LPCVOID)address,&mbi,sizeof(MEMORY_BASIC_INFORMATION));

            // display all of the allocated memory block from address to address+mbi.RegionSize-1
            if (mbi.State==MEM_COMMIT)
                  {
                  wsprintf(buf,"%08x - %08x %s\n",address,address+mbi.RegionSize-1,
                        mbi.Type==MEM_IMAGE?"MEM_IMAGE":(mbi.Type==MEM_MAPPED?"MEM_MAPPED":"MEM_PRIVATE"));
                  OutputDebugString(buf);
                  }
            address+=mbi.RegionSize;
            }
      CloseHandle(proc);
      }
0
 
mmadhusoAuthor Commented:
Thanks mike

but MEMORY_BASIC_INFORMATION
contains information about a range of pages in the virtual address space of a process

how about getting information in the physical address space ,

i need to examime the physical address space , the actual pages that are present in the memory not the
virtual memory

can u help me in this context
0
 
Mikeh926Commented:
Oh, so you want to know for each commited page if it is currently allocated to physcial ram, or stored in the swap file?

Well, all memory addresses in Windows are Virtual, so the only way you can access physical memory is via a virtual memory pointer.

If you need to examine the memory, just access it and it will be paged in automatically if needed.

As far as I know, there are no WIN32 API functions that let you get information about the current mapping between virtual and physcial memory. One way you could do this would be to write a kernel mode driver/service that uses the Kernel Mm... functions, such as MmGetPhysicalAddress() or MmIsAddressValid(). In principle you could use these to go through memory and work out which pages are paged in, however it's a dynamic system so there is no guarentee that pages won't be paged in or out whilst you are scanning them. The other way would be to somehow get hold of the MDL for the process you are interested in. This is the mapping table that the kernel maintains to map virtual to physical addresses. However, this is a bit beyond my area of expertise.

Regards,
Mike.


0
 
mmadhusoAuthor Commented:
yes u got it

Basically i need to test the idleness of a page in the physical memory

i.e. if a process keeps allocating large amount of memory in an infinite loop
and the allocated memory is not used ,  just allocated and never used again,

 say    while (1)
            {  int  a[10000] }

this just allocates memory and never used and the program is not killed ,

so there is some memory in the physical memory that is being wasted i.e not used at all ,

i want to claim them back ,thats the reason i wanted to know the workingset size & which particular set of
pages are not used for a long time

am i clear ??  
         
0
 
Mikeh926Commented:
I think that what you are trying to do is not possible and I not quite sure what you are trying to achieve. If you want to write something that frees unused memory that's fine, but you don't really know if the memory is wasted.

You can't just free memory pages belonging to some other process because they haven't been access for a while. If you do then that will likley result in a crash, unless you wait for a really long time, and go through every single application feature/code path before doing so (which unless it's a real simple app, will be virtually impossible).

In any case, if they haven't been accessed for a while they will be automatically paged out into the swap file. This will free up physical memory. So pages that you describe as being "wasted" do not waste physical ram. Ok, so they will still be occupying a section of virtual memory and the swap file, but that's only for that particular process which won't affect any other processes.

All you are going to effectivelly do is reduce the size of the swap file at the risk of causing the other process to crash if it suddenly decides it needs to access the memory that it had previously allocated.


0
 
mmadhusoAuthor Commented:
hi Mike

I understand what your are trying say

but is it possible by any chance to take away pages allocated to a process ?,
just the crude way even of it degrades the system ,

i will take care of all other problems caused by this ,

please let me know  
0
 
Mikeh926Commented:
Ok, you could use VirutalQueryEx() to make a list of all of the pages that have been allocated by the process (make sure you exclude any memory mapped files and exe images). I think these are the ones marked as MEM_PRIVATE.

You could use VirtualFreeEx() to free up any of these pages.

Quite how you decide which pages to free and when is your problem. You bascially need to know which pages are accessed frequently and which are not.

The only way I can think of doing this would be to use VirtualProtectEx() and change the state of the pages you want to monitor to PAGE_GUARD. This will raise an exception when each page is first accessed and you can flag that page as in use. Periodically you would need to reset the PAGE_GUARD flag on each page. You would end up with a list of pages that had never been accessed and maybe these are the ones you could free (or decommit). The problem with this is that you would need to inject an exception handler into the process to hadnle the STATUS_GUARD_PAGE exception.
0
 
mmadhusoAuthor Commented:
Hi Mike

But   in  VirtualFreeEx() ,the second parameter is   --- LPVOID lpAddress,

A pointer to the starting address of the region of memory to be freed.   how do i get this knowing the handle or the pid of
the process . I just cannot find a function that gives me the base address of the process

also i guess in VirtualFreeEx   --  lpAddress must be the base address returned by the VirtualAllocEx

so is it that VirtualFreeEx should be used in pair with VirtualAllocEx


please comment on it
0
 
Mikeh926Commented:
Calls to VirtualFree and VirtualAlloc do not have to be paired together.

You can pass any address you like to VirtualFreeEx and it will free that memory page (or pages dependning on the dwSize parameter). VirtualAlloc just allocates the next convenient memory block consisting of contiguous pages and returns you a pointer to it.

If you allocated 2 pages, you could free each page separately if you wanted to.

0
 
mmadhusoAuthor Commented:
ok

So Is there a way to get the  starting address of a process , i.e. the base address of a process ,
0
 
Mikeh926Commented:
Each process address space has the same starting address - 0x00000000!. Normally the main module (the exe) loads at address 0x00400000. DLL's and allocated memory is above that.
0
 
mmadhusoAuthor Commented:

hi

VirtualFreeEx(hProcess,(LPVOID)0x00000000,4096,MEM_DECOMMIT);

i have given the parameters ,  but gives me an  invalid address  error in the Error Code
0
 
Mikeh926Commented:
Well you will probably get an invalid address if the memory at location 0 is not commited, or cannot be decommited because it's locked. You need to walk through the memory blocks using VirtualQueryEx() as I described earlier to find blocks that are allocated.
0
 
mmadhusoAuthor Commented:
answer accepted
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Cloud Class® Course: Microsoft Office 2010

This course will introduce you to the interfaces and features of Microsoft Office 2010 Word, Excel, PowerPoint, Outlook, and Access. You will learn about the features that are shared between all products in the Office suite, as well as the new features that are product specific.

  • 9
  • 8
Tackle projects and never again get stuck behind a technical roadblock.
Join Now