Mike on the MATLAB Desktop
August 17th, 2009
Calling Java from MATLAB, Memory Issues
Following up with my previous post about using Java objects in MATLAB, this week I’m going to discuss the memory issues that can crop up.
When a Java object is created in the MATLAB workspace, it is actually created in the Java heap space and not the main memory used by MATLAB. On a 32-bit windows machine, MATLAB might have up to 3 GB available for creating matrices and other MATLAB objects but only 64 or 128 MB (by default) for creating java objects. To find out how much memory is available for creating Java objects, there are three numbers of importance: the free memory, the total memory, and the max memory.
The free memory is the number of bytes available in the heap space for creating new objects. The total memory is the number of bytes allocated to the total heap space which is the size of the objects created + the free memory. When the amount of free memory starts to get low, java will increase the total memory until it equals the the max memory. You can see this in the following animated graph, where the green (total memory) is bumped up when I create the large array of java doubles. The jumps in the blue represent the objects created as I manipulated the editor and command window to set up this demo, and the dips are when those objects get garbage collected, freeing up memory. The actual double array isn’t shown on this graph as it is created and cleared faster than the sampling time of the graph.
This is the demo that was running at the time of the jump: you can see the commands to discover the java memory, as well as the fact that the array creation ups the used java memory but does not affect the memory for MATLAB array creation:
free = java.lang.Runtime.getRuntime.freeMemory
total = java.lang.Runtime.getRuntime.totalMemory
max = java.lang.Runtime.getRuntime.maxMemory
feature('memstats')
x = javaArray('java.lang.Double',400000);
for i=1:400000
x(i)=java.lang.Double(i);
end
free =
13271784
total =
65470464
max =
130875392
Physical Memory (RAM):
In Use: 1911 MB (77755000)
Free: 1655 MB (677f0000)
Total: 3567 MB (def45000)
Page File (Swap space):
In Use: 2205 MB (89dd3000)
Free: 3243 MB (cab14000)
Total: 5448 MB (1548e7000)
Virtual Memory (Address Space):
In Use: 585 MB (24928000)
Free: 1462 MB (5b6b8000)
Total: 2047 MB (7ffe0000)
Largest Contiguous Free Blocks:
1. [at 320b5000] 459 MB (1cb9b000)
2. [at 4edf6000] 279 MB (117da000)
3. [at 21810000] 263 MB (107f0000)
4. [at 605d9000] 146 MB ( 9217000)
5. [at 6d346000] 71 MB ( 470a000)
6. [at 697f6000] 58 MB ( 3a3a000)
7. [at 71ce7000] 19 MB ( 1319000)
8. [at 73026000] 18 MB ( 126a000)
9. [at 7e4a1000] 18 MB ( 124f000)
10. [at 7d1d7000] 18 MB ( 1239000)
======= ==========
1352 MB (548cb000)
ans =
481931264
free = java.lang.Runtime.getRuntime.freeMemory
total = java.lang.Runtime.getRuntime.totalMemory
max = java.lang.Runtime.getRuntime.maxMemory
feature('memstats')
free =
31137576
total =
102739968
max =
130875392
Physical Memory (RAM):
In Use: 1919 MB (77f2a000)
Free: 1648 MB (6701b000)
Total: 3567 MB (def45000)
Page File (Swap space):
In Use: 2238 MB (8be27000)
Free: 3210 MB (c8ac0000)
Total: 5448 MB (1548e7000)
Virtual Memory (Address Space):
In Use: 584 MB (248b8000)
Free: 1463 MB (5b728000)
Total: 2047 MB (7ffe0000)
Largest Contiguous Free Blocks:
1. [at 320b5000] 459 MB (1cb9b000)
2. [at 4edf6000] 279 MB (117da000)
3. [at 21810000] 263 MB (107f0000)
4. [at 605d9000] 146 MB ( 9217000)
5. [at 6d346000] 71 MB ( 470a000)
6. [at 697f6000] 58 MB ( 3a3a000)
7. [at 71ce7000] 19 MB ( 1319000)
8. [at 73026000] 18 MB ( 126a000)
9. [at 7e4a1000] 18 MB ( 124f000)
10. [at 7d1d7000] 18 MB ( 1239000)
======= ==========
1352 MB (548cb000)
ans =
481931264
One caution is that this space is shared between any objects you might create as well as objects created by the Desktop, Editor, Current Folder, etc. Once all the java memory is used up, there is the potential of locking up MATLAB, as there might not be enough room to even create an out-of-memory dialog.
There is a solution to running out of Java memory that is usually safe, although sometimes produces unintended consequences if the numbers are made too large. That is to create or modify a java.opts file in the MATLAB startup directory. This allows you to pass JVM options (such as the total and max memory for the heap) on MATLAB startup. Instructions can be found at this solution.
By
Michael Katz
Mike is a developer on the MATLAB Mobile team. When not describing himself in the third person, biking, homebrewing, or rooting for the home team, he's busy trying to make the world a better place for programming.
18:49 UTC |
Posted in java, Uncategorized |
Permalink |
8 Comments »
You can follow any responses to this entry through the RSS 2.0 feed.
You can skip to the end and leave a response. Pinging is currently not allowed.
Leave a Reply
|
Hi Michael,
Thank you for the nice article, very informative. I am wondering what tool you were using to monitor the memory usage and produce the animated graph?
Best,
Jason
@Jason,
I made this graph with a Java profiling program called JProfiler on top of a debug build of MATLAB.
Hi Mike,
Can i call C function instead of C dll from Matlab?
@enkh,
I’m not sure what you’re asking. For C code to be useful it has to be compiled and linked (hence the dll). You can create a C MEX function, compile that and use it from MATLAB, if that’s what you’re asking?
Mike:
It’s a good articles. But I have a different question to ask:
I called a java class in my .m file 350 times, it works perfect. then I put all the java class and libraries in two jar file, one has java libraries, the other one has java classes. Now the program works ok, but I wonder if there will be any special requirement when I compile the m file into executables?
Thanks
Shirley
I have a similar problem with a GUI I’ve written, and the matlab garbage collector is not efficient enough, but when I use the “Perform GC” on the JMC I get a very good collection.
the GUI is intended for end users.
is there a way to improve the collection without installing a java heap monitoring tool?
@Irad – you can activate Java’s garbage collector programmatically by calling: java.lang.System.gc
Of course, this does not really solve true memory problems. You actually need to do the much harder work of identifying your memory leaks and solving them. System.gc is merely a temporary band-aid.
When I call a Java method from Matlab, is the memory copied to the Java heap? And then when I return data from Java to Matlab is that data copied to the Matlab heap? If so, is this a big performance concern that I should try to optimize (reduce the passing of data between heaps)? Thanks!