amos
amos

Reputation: 5402

Track native memory usage from Java?

Is there any way I can log native memory usage from Java, i.e., either native memory directly or the total memory the process is using (e.g., ask the OS)?

I'd like to run this on user's machines behind the scenes, so the NativeMemoryTracking command line tool isn't really the most appealing option. I already log free/max/total heap sizes.

Background: A user of my software reported an exception (below) and I have no idea why. My program does use SWIG'd native code, but it's a simple API, I don't think it has a memory leak, and wasn't on the stacktrace (or run immediately before the error). My log indicated there was plenty of heap space available when the error occurred. So I'm really at a loss for how to track this down.

java.lang.OutOfMemoryError: null
    at java.io.RandomAccessFile.writeBytes0(Native Method) ~[na:1.7.0_45]
    at java.io.RandomAccessFile.writeBytes(Unknown Source) ~[na:1.7.0_45]
    at java.io.RandomAccessFile.write(Unknown Source) ~[na:1.7.0_45]

The error occurred on Windows (7 or 10)(?) from within webstart, configured with these parameters:

<java href="http://java.sun.com/products/autodl/j2se" initial-heap-size="768m" java-vm-args="" max-heap-size="900m" version="1.7+"/>

Upvotes: 6

Views: 2156

Answers (4)

amos
amos

Reputation: 5402

I ended up using this code which asks the OS for RSS and Peak memory usage. It was straightforward for me to add since I already have a SWIG module set up. The code might not be threadsafe since I hit a random malloc exception when I was testing, meaning I'm not sure I want to keep it in there.

I'm really surprised the JVM doesn't provide a way to do this. Please someone let me know if there's a way.

Upvotes: 1

Jun
Jun

Reputation: 109

public final void writeBytes(String s) throws IOException {
    int len = s.length();
    byte[] b = new byte[len];
    s.getBytes(0, len, b, 0);
    writeBytes(b, 0, len);
}

Looking at the source, it is possible that a sufficiently large String would have caused out of memory error. I suspect that your heap log was done before this happened which explains the free heap space you saw. I suggest you verify if this is the case and if yes, limit the String size and/or increase the heap size.

Upvotes: -1

mhasan
mhasan

Reputation: 3709

If you want tp track down the JVM memory on your certain method or lines of code you can use the Runtime API.

    Runtime runtime = Runtime.getRuntime();
    NumberFormat format = NumberFormat.getInstance();

    long maxMemory = runtime.maxMemory();
    long allocatedMemory = runtime.totalMemory();
    long freeMemory = runtime.freeMemory();

System.out.println("free memory: " + format.format(freeMemory / 1024));
System.out.println("allocated memory: " + format.format(allocatedMemory / 1024));
System.out.println("max memory: " + format.format(maxMemory / 1024));
System.out.println("total free memory: " + format.format((freeMemory + (maxMemory - allocatedMemory)) / 1024));

Upvotes: 2

Good Game Industries
Good Game Industries

Reputation: 113

Here is a snippet of code that sets the string equal to the amount of memory used(mb)/total memory(mb) You can then use this to log however you want!

Runtime instance = Runtime.getRuntime();
String mem = "Memory Used: "+ (instance.totalMemory() - instance.freeMemory()) / mb +"MB ("+
   (int)((instance.totalMemory() - instance.freeMemory())*1.0/instance.totalMemory()*100.0)+"%)"

Upvotes: 0

Related Questions