Friday 17 January 2014

Memory Booster

Introduction 
Visit for more details:
http://www.codeproject.com/Articles/712220/Release-memory-of-processes-currently-running-Memory
Memory Booster:


This is an application which releases memory for currently running processes. Managing memory is crucial part and many times process contains unused or unnecessary pages in their working set (i.e. physical memory currently using by process). So it is necessary to remove these unnecessary memory pages from physical memory to optimize RAM, which increases performance of PC.  
Background  
What is working Set? How it gone to affect on memory? 
The Working Set of a process is the set of pages in the virtual address space of the process that are currently resident in physical memory. The working set contains only pageable memory allocations, non-pageable memory allocations such as Address Windowing Extensions (AWE) or large page allocations are not included in the working set.
When a process reference pageable memory that is not currently in its working set, a page fault occurs. The system page fault handler attempts to resolve the page fault and, if it succeeds, the page is added to the working set. (Accessing AWE or large page allocations never causes a page fault, because these allocations are not pageable.)
A hard page fault must be resolved by reading page contents from the page's backing store, which is either the system paging file or a memory-mapped file created by the process. A soft page fault can be resolved without accessing the backing store. A soft page fault occurs when:
·         The page is in the working set of some other process, so it is already resident in memory.
·         The page is in transition, because it either has been removed from the working sets of all processes that were using the page and has not yet been repurposed, or it is already resident as a result of a memory manager prefetch operation.
·         A process references an allocated virtual page for the first time (sometimes called a demand-zero faults).
Above discussion makes conclusion that working set is amount of memory (physical i.e. RAM) used by process currently. But this not means that every page in process’s working set is currently used by process. So we need to remove those pages from working set i.e. from physical memory currently used by process.
This is what our main purpose of this application. We are removing unused pages from process’s working set.
Application offers following functionality
  1. On start up it shows all currently running processes.
  2. Restart: It help user to restart one or more selected processes (application).
  3. Kill: It help user to kill one or more selected processes (application).
  4. Free: It help user to free memory for one or more selected processes.
  5. Free All: It helps user to free memory for all running processes.
  6. Start New Task: It helps user to start new task.
Main window also contains menu bar consisting of 3 menus and 8 sub menus. But 2 menus helps us to use supplementary tasks as:·         Get module list of selected process. ·         DLL dependent processes 
Requirements
Need to install .Net Framework 4.0 on your machine

Application Setup
Extract the Project and follow below two simple processes
  1. Register OptimizeMemory.dll, DLLDependProc.dll and ProcessInformation.dll libraries (DLL) 
  2. Now run Memory Booster.exe   
About Application
Memory Booster application is mainly divided in two parts i.e.

1.   C#  
Mainly focus on User Interface & Function Calling. All below 3 DLL are getting called from this project.2.   C++ COM DLL
 It consists of three C++ COM DLL projects as following:
OptimizeMemory: This project fulfills our main purpose to release memory currently
unused by process.
DLL Dependent Processes: This project is used to remove all processes currently running which uses specified DLL (browsed manually). 
Process Information: This project retrieves library modules (i.e. dlls) used by selected process. 

Projects 2 and 3 are supplementary projects but not fulfill our main purpose of release process’s memory.
Using the code 
We use EmptyWorkingSet function from PSAPI library module which take handle to process as parameter and return the non zero on success and 0 on failure.

Parameters: Handle to process
Return value:    
  1. If the function succeeds, the return value is nonzero.     
  2. If the function fails, the return value is zero. 
To free memory for all process: 
STDMETHODIMP CReleaseProcessMemory::ReleaseAllProcessMemory(VARIANT_BOOL* vbMemoryReleased){          AFX_MANAGE_STATE(AfxGetStaticModuleState());           // Get the list of process identifiers.          DWORD aProcesses[1024], cbNeeded,cProcesses;          unsigned int i;            //This returns a list of handles to processes running on          //the system as an array.          if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ))                   return S_OK;            // Calculate how many process identifiers were returned. 
          cProcesses = cbNeeded / sizeof(DWORD);            for ( i = 0; i < cProcesses; i++ )          {                   if(aProcesses[i] != 0 )                   {                             // Get a handle to the process.                               HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |                             PROCESS_VM_READ | PROCESS_ALL_ACCESS, FALSE, aProcesses[i] );                                     // Get the process name. 
                             if (NULL != hProcess )                             {                                      TCHAR szProcessName[MAX_PATH] = TEXT("<unknown>");                                      HMODULE hMod;                                      DWORD cbNeeded;                                                 if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod), &cbNeeded) )                                      {                                                //This function returns the short name for a module,                                                //typically the file name portion of the EXE or DLL                                                GetModuleBaseName( hProcess, hMod, szProcessName,                                                          sizeof(szProcessName)/sizeof(TCHAR));                                      }                                                 if( !EmptyWorkingSet(hProcess) )                                      {                                                *vbMemoryReleased = VARIANT_FALSE;                                      }                                      else                                       {                                                *vbMemoryReleased = VARIANT_TRUE;                                      }                             }                           }          }           return S_OK;} 
Points of Interest
Interesting part of this application is calling unmanaged code (i.e. C++ COM dll) in managed code (i.e. in C# application code). For details go following example snippet or attached source code.  
Process for calling C++ COM dll from C# project:

Steps:1.   Add reference for dll project in c# project.
2.   Declare COM dll interface object as:
private OptimizeMemoryLib.ReleaseProcessMemory objOptimizeMemory;
3.   Create object in constructor as:
objOptimizeMemory = new OptimizeMemoryLib.ReleaseProcessMemory();4.   Finally call dll function as:
objOptimizeMemory.ReleaseAllProcessMemory();