Jump to content
Excelsior Forums
Erhune

Limit of 64 Mb of native memory

Recommended Posts

Hello,

I'm working for a French software company, and we are considering using JET to compile one of our apps into native code, but we're having some problems its management of native memory. Our app is using JOGL intensively for display, and JOGL needs to allocate native memory in order to store textures. We browsed JOGL source code, and found that its texture allocation routines simply uses ByteBuffer.allocateDirect() to reserve memory. But it seems that the JET runtime doesn't allow an app to allocate more than 64 Mb of DirectByteBuffers at any given time. This can be highlighted with the following simple test :

public class Test {

public static void main(String[] args) {
	ArrayList<ByteBuffer> buffers = new ArrayList<ByteBuffer>();
        for (int i = 0; i < 128; i++) {
        		ByteBuffer buf = ByteBuffer.allocateDirect(1024*1024);
        	buffers.add(buf);
        		System.out.println("Allocated so far: " + buffers.size() + " Mb");
        }
}

// OK for Sun JVM, KO for JET

}

On a WinXP Pro SP2 machine and both Sun JDK 1.5.0_6 and 1.6.0_3, this code executes fine provided you use -Xmx129M. On the same machine & OS, compiled with JET 6.0 Evaluation, the application crashes with the following output :

Allocated so far: 62 Mb
Allocated so far: 63 Mb
Allocated so far: 64 Mb
Exception in thread "main" java.lang.OutOfMemoryError: Direct buffer memory
at java.lang.Void.<unknown>(Unknown Source)
at java.lang.Void.<unknown>(Unknown Source)
at java.lang.Void.<unknown>(Unknown Source)
at java.lang.Void.<unknown>(Unknown Source)

Whatever value I use for maximum heap size in the project, it stops when trying to allocate more than 64 Mb of native memory at any time. Of course, if I release some of these buffers, it works just fine :

public class Test2 {

public static void main(String[] args) {
	ArrayList<ByteBuffer> buffers = new ArrayList<ByteBuffer>();
        for (int i = 0; i < 128; i++) {
        		ByteBuffer buf = ByteBuffer.allocateDirect(1024*1024);
        	buffers.add(buf);
        		System.out.println("Allocated so far: " + buffers.size() + " Mb");
		if (i == 64) {
			buffers.clear();
		}
        }
}

// OK for Sun JVM & JET

}

Is there any way to increase this maximum size of 64 Mb? This is critical for us to be able to evaluate the JET-compiled version of our app, before we consider buying the product.

Sincerly yours,

--

Matthieu Guillemot

Share this post


Link to post
Share on other sites
Is there any way to increase this maximum size of 64 Mb?

Sure.

The JET Runtime uses another policy to set the limit of direct memory size and it causes such problems. We have already corrected it for the next version of Excelsior JET but now you can use the following workaround.

To avoid this kind of OutOfMemoryError, define sun.nio.MaxDirectMemorySize property and set it to the max number of bytes which will be available for java.nio direct buffers.

By default, direct buffer area is limited by 64 Mb.

Note, however, that values with "m" or "k" (e.g. "200m" or "12000k") are not allowed - only plain numbers can be specified.

To check if it helps, write a simple .bat file

 

--------------------- run.bat

SET JETVMPROP=-Dsun.nio.MaxDirectMemorySize:200000000

YourApp.exe

---------------------------

Run this .bat file and ensure that the problem has gone.

To set the property permanently, open your project in JET Control Panel, set the sun.nio.MaxDirectMemorySize property on page Start, and recompile your application.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×