0

I need to compare the memory consumption of the same algorithms when executed in C, C++ and Java. After doing some reading I figured out that measuring maximum resident set size is the best indicator of memory consumption. For C/C++ I am able to use getrusage() to get the data, but for Java I am not able to find any equivalent.

bmargulies
  • 91,317
  • 38
  • 166
  • 290
varu
  • 13
  • 2

3 Answers3

2

Comparing memory usage between Java and C / C++ is difficult. While measures like the maximum resident set size (RSS) are meaningful in C / C++, they are not in Java.

  • In C / C++, the maximum RSS is a good approximation to maximum memory usage.

  • In Java, the RSS at any point in time is likely to include parts of the heap that currently hold garbage and free space. Furthermore, the maximum RSS is going to be strongly influenced by your choice of garbage collection parameters. The way that GC ergonomics work means that it is a good idea to be generous with the heap sizes (to reduce GC overheads). But that means that your maximum RSS will be larger.

On the other hand, maximum RSS is not a perfect measure of memory usage in C / C++ programs:

  • The "resident" in RSS means that the system is counting physical memory pages not virtual pages. If the system is short on physical memory, your application's non-shared virtual memory usage (which is what you really need to measure) could be significantly larger that the max RSS.

  • If your C / C++ application is using malloc'ed memory, and it is repeatedly mallocing and freeing, there is the possibility that you will get significant heap fragmentation and that that will inflate the the max RSS value.


Finally, if you did want to try to use getrusage in Java, the way to do it would be to write a small native code procedure to make the call, and invoke the procedure via JNI or JNA.

Stephen C
  • 632,615
  • 86
  • 730
  • 1,096
  • Just out of curiosity, how about in python? Is Maximum RSS a good approximation of maximum memory usage. – varu Dec 27 '15 at 23:13
  • @varu - Maybe yes, maybe no. This URL implies that getrusage gives a "good read" on maximum memory usage (http://pythonforbiologists.com/index.php/measuring-memory-usage-in-python/) but this may depends on the Python implementation, – Stephen C Dec 28 '15 at 14:51
0

JMX is the usual way to get those statistics from a Java application internally E.g. How do I access memory usage programmatically via JMX?

Interface MemoryMXBean Documentation.

This gives you Heap on virtual memory through, but that should be close to RSS as you'll get from within the JVM currently. Unless you use JNI/JNA/JNR to call getrusage() in a non-cross platform way.

E.g This following example uses JNA for Closure, ( another JVM language, similar should work with Java ) https://github.com/circleci/clj-getrusage

Community
  • 1
  • 1
kervin
  • 11,246
  • 5
  • 38
  • 57
  • Thanks I'll look into JMX! And could you elaborate on how I could call getrusage() in a non-cross platform way? – varu Dec 27 '15 at 22:25
-1

Perhaps this tutorial might be of use to you, or the MemoryUsage Class.

from the tutorial:

public class PerformanceTest {
  private static final long MEGABYTE = 1024L * 1024L;

  public static long bytesToMegabytes(long bytes) {
    return bytes / MEGABYTE;
  }

  public static void main(String[] args) {
    // I assume you will know how to create a object Person yourself...
    List<Person> list = new ArrayList<Person>();
    for (int i = 0; i <= 100000; i++) {
      list.add(new Person("Jim", "Knopf"));
    }
    // Get the Java runtime
    Runtime runtime = Runtime.getRuntime();
    // Run the garbage collector
    runtime.gc();
    // Calculate the used memory
    long memory = runtime.totalMemory() - runtime.freeMemory();
    System.out.println("Used memory is bytes: " + memory);
    System.out.println("Used memory is megabytes: "
        + bytesToMegabytes(memory));
  }
} 

The MemoryUsage Object description:

A MemoryUsage object represents a snapshot of memory usage. Instances of the MemoryUsage class are usually constructed by methods that are used to obtain memory usage information about individual memory pool of the Java virtual machine or the heap or non-heap memory of the Java virtual machine as a whole. A MemoryUsage object contains four values:

  • init represents the initial amount of memory (in bytes) that the Java virtual machine requests from the operating system for memory management during startup. The Java virtual machine may request additional memory from the operating system and may also release memory to the system over time. The value of init may be undefined.
  • use represents the amount of memory currently used (in bytes). committed represents the amount of memory (in bytes) that is guaranteed to be available for use by the Java virtual machine. The amount of committed memory may change over time (increase or decrease). The Java virtual machine may release memory to the system and committed could be less than init.
  • committed will always be greater than or equal to used.
  • max represents the maximum amount of memory (in bytes) that can be used for memory management. Its value may be undefined. The maximum amount of memory may change over time if defined. The amount of used and committed memory will always be less than or equal to max if max is defined. A memory allocation may fail if it attempts to increase the used memory such that used > committed even if used
Appelemac
  • 142
  • 5