Getting the current memory usage of a Process in windows with Java

You will have to use JNI for this. Using the following code, we will create a DLL that provides the method getProcessWorkingSet which will return the current working set size, and the method getProcessVMSize which will return the current pagefile usage. The working set size is the memory size as shown in the Windows Task Manager. The pagefile usage corresponds with the VM Size in the Windows Task Manager.

From MSDN:
Working set size: The working set is the amount of physical memory assigned to a process. If the working set is too small, the process incurs a high number of page faults as it repeatedly accesses the disk drive to locate data not currently in memory. If the working set is too large, fewer page faults occur, but the process retains memory that it no longer needs, and which might be required by other processes. A steady increase in the size of the working set can mean that the process is not releasing memory appropriately.

MemUsage.java:

public class MemUsage
{
   public native int getProcessWorkingSet();
   public native int getProcessVMSize();
}

Compile it and run javah on it to create the memusage.h header file:

javah -o memusage.h MemUsage

It generates the C header file memusage.h:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class MemUsage */
 
#ifndef _Included_MemUsage
#define _Included_MemUsage
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     MemUsage
 * Method:    getProcessWorkingSet
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_MemUsage_getProcessWorkingSet
  (JNIEnv *, jobject);
 
/*
 * Class:     MemUsage
 * Method:    getProcessVMSize
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_MemUsage_getProcessVMSize
  (JNIEnv *, jobject);
 
#ifdef __cplusplus
}
#endif
#endif

The implementation of these functions were put in memusage.c:

#include <windows.h>
#include <stdio.h>
#include <iphlpapi.h>
#include <Psapi.h>
#include "memusage.h"
 
/*
 * Class:     MemUsage
 * Method:    getProcessWorkingSet
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_MemUsage_getProcessWorkingSet
  (JNIEnv *env, jobject obj) {
   PROCESS_MEMORY_COUNTERS  pmc;
 
   pmc.cb = sizeof(pmc);
 
   if (!GetProcessMemoryInfo(GetCurrentProcess(),&pmc,sizeof(pmc)))
      return;           // (must be running on Win9x)
 
   return pmc.WorkingSetSize;
}
 
/*
 * Class:     MemUsage
 * Method:    getProcessVMSize
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_MemUsage_getProcessVMSize
  (JNIEnv *env, jobject obj) {
   PROCESS_MEMORY_COUNTERS  pmc;
 
   pmc.cb = sizeof(pmc);
 
   if (!GetProcessMemoryInfo(GetCurrentProcess(),&pmc,sizeof(pmc)))
      return;           // (must be running on Win9x)
 
   return pmc.PagefileUsage;
}

I used cygwin to develop a Windows DLL from this in the following way:

gcc -mno-cygwin -I/usr/include -Ic:/jdk1.3.1/include -Ic:/jdk1.3.1/include/win32
 -shared memusage.c -Wl,--add-stdcall-alias -o MemUsage.dll -lpsapi

This DLL now allowed me to get the current memory usage and page file usage on Windows. Here’s an example:

Main.java:

public class Main
{
   public static void main(String []args) throws Exception {
      System.loadLibrary("MemUsage");
      System.out.println("MemUsage loaded");
 
      MemUsage mem = new MemUsage();
      System.out.println("Current process working set: " + mem.getProcessWorkingSet() / 1024 + "K");
      System.out.println("Current process VM size:     " + mem.getProcessVMSize() / 1024 + "K");
       
      System.in.read();
   }
}

Sample run:

C:\experiments\java\workingset>java Main
MemUsage loaded
Current process working set: 4868K
Current process VM size:     5780K
  
C:\experiments\java\workingset>java Main
MemUsage loaded
Current process working set: 4872K
Current process VM size:     5784K

For those who don’t have cygwin installed or just want to start using this library right away, here it is:

MemUsage.dll