0

I can't for the life of me get the GC to work consistently so to measure the amount of memory used by instances of some class. GC just isn't predictable (spent 2 days googling it, so please if you provide references, please make sure you tried it, and it worked, or else i most likely already know about ur solution )

I'm using Java EE 5, so JVisuamVM isn't available for me.

So i thought about going JNI, starting my processes from C++ code, and getting the amount of memory they use, since i heard C++ can do that.

I have already used the JNI for "hello world" kinds of things, so i don't need a step by step intro, I would just need to know how i start another process from C++ (Something similar to Runtime.getRuntime().exec("java MyClassWithMainMethod");), and how do i get the memory used by that process.

Arjan Tijms
  • 37,782
  • 12
  • 108
  • 140
vlad-ardelean
  • 7,480
  • 15
  • 80
  • 124
  • there is no standard way to do this, what operating system are you working on? – CashCow Feb 10 '12 at 08:34
  • I don't get your original problem. You want to measure the amount of memory one specific class uses up and you can do so by calculating that amount from the total memory used, correct? Have you considered using the MXBeans and if so, what is wrong? What do you mean by "GC isn't predictable"? The timing or the result of collections? Have you tried different GCs? – Jonathan Feb 10 '12 at 09:29
  • C++ can do that for memory in C++. The JVM allocates the maximum heap size on startup, so it will appear to be 100% all the time. I suggest you use a memory profiler which does work with your system. – Peter Lawrey Feb 10 '12 at 10:35
  • I disagree. The processmonitor in Windows shows the current memory consumption, not the currently allocated memory. So there is a possibility to externally monitor the memory consumption. – Jonathan Feb 10 '12 at 11:02

2 Answers2

2

If you are having a memory leak, try and use JProfiler or any other Java profiler.

To create a process in Windows:

STARTUPINFO info={sizeof(info)};
PROCESS_INFORMATION processInfo;
if (CreateProcess(path, cmd, NULL, NULL, TRUE, 0, NULL, NULL, &info, 
    &processInfo))
{
    PROCESS_MEMORY_COUNTERS pmc;
    if ( GetProcessMemoryInfo( processInfo.hProcess, &pmc, sizeof(pmc)) )
    {
        printf( "\tPageFaultCount: 0x%08X\n", pmc.PageFaultCount );
        printf( "\tPeakWorkingSetSize: 0x%08X\n", 
              pmc.PeakWorkingSetSize );
        printf( "\tWorkingSetSize: 0x%08X\n", pmc.WorkingSetSize );
        printf( "\tQuotaPeakPagedPoolUsage: 0x%08X\n", 
              pmc.QuotaPeakPagedPoolUsage );
        printf( "\tQuotaPagedPoolUsage: 0x%08X\n", 
              pmc.QuotaPagedPoolUsage );
        printf( "\tQuotaPeakNonPagedPoolUsage: 0x%08X\n", 
              pmc.QuotaPeakNonPagedPoolUsage );
        printf( "\tQuotaNonPagedPoolUsage: 0x%08X\n", 
              pmc.QuotaNonPagedPoolUsage );
        printf( "\tPagefileUsage: 0x%08X\n", pmc.PagefileUsage ); 
        printf( "\tPeakPagefileUsage: 0x%08X\n", 
              pmc.PeakPagefileUsage );
    }
    ::WaitForSingleObject(processInfo.hProcess, INFINITE);
    CloseHandle(processInfo.hProcess);
    CloseHandle(processInfo.hThread);
}

Links:
http://msdn.microsoft.com/en-us/library/ms682512(VS.85).aspx
http://msdn.microsoft.com/en-us/library/ms683219.aspx

Alin Stoian
  • 1,122
  • 1
  • 12
  • 24
1

There is no platform-independent way to do it, but you start the java process just like you would any command-line process. On UNIX this would probably mean fork() and exec(), for the first call you would do an if(( pid = fork() )) giving you the process id of the new process (which you then exec on). (Note that the else() means you're in the current process).

Once you have executed and started the process, you will know its process id (it was returned by fork())

and you can use the system tools to check its memory use as with: How to measure actual memory usage of an application or process?

Community
  • 1
  • 1
CashCow
  • 30,981
  • 5
  • 61
  • 92