Forum Stats

  • 3,853,771 Users
  • 2,264,266 Discussions
  • 7,905,444 Comments

Discussions

EJB and JNI: OutOfMemoryError

843829
843829 Member Posts: 49,201
edited Sep 10, 2010 10:33AM in Java Native Interface (JNI)
Hi,
I have a J2EE application running on JBoss 4.2.2 (Windows platform): I need to call a C DLL so I'm using JNI. After some time the application raises the following error

...
java.lang.OutOfMemoryError: unable to create new native thread
at java.lang.Thread.start0(Native Method)
at java.lang.Thread.start(Unknown Source)
...

The JVM is started using 512MB as both min and max heap size (no other memory or stack options). The same app without the DLL integration runs fine so it seems to me that the problem is caused by the DLL integration via JNI. I've checked the DLL C code and memory is correctly released.
I tried to wrap the DLL with a MBean but I obtain the same error.
I've checked the virtual memory occupation of the JVM during the load test and it seems to grow faster with the DLL integration: without the DLL the virtual memory occupation is much more stable.

What do you think? Should I tune the garbage collector with some options?

Thanks in advance,
Andrea

Comments

  • 843829
    843829 Member Posts: 49,201
    sorry, forgot to mark the post as a question.

    Andrea
  • jschellSomeoneStoleMyAlias
    jschellSomeoneStoleMyAlias Member Posts: 24,877 Gold Badge
    Andrea_Giovannini wrote:
    After some time the application raises the following error
    That suggests to me that you have a resource problem. Such as creating threads and never exiting from them.
  • 843829
    843829 Member Posts: 49,201
    Hi jschell,
    the Java part of the application has no problems with resources (I've checked and double-checked): if we exclude the DLL the only external resource I access is the database and connections are correctly returned to the connection pool (it's a J2EE application running on JBoss).
    If I stress a version of the application without DLL integration then OutOfMemoryError is never raised and memory occupation seems stable (this suggests me that there aren't problems with the Java part).
    If I stress the application with the DLL integration then I get the OutOfMemoryError: I have the impression that the problem is caused by the DLL, but I don't know what to do :-(
    I've found in several answers to the same problem (in different forums) that a possible solution can be reducing the heap size for the JVM but I can't do it: the application starts with 512MB as heap min and max size and this is the minimum in order to obtain good performance for the application.

    Andrea
  • jschellSomeoneStoleMyAlias
    jschellSomeoneStoleMyAlias Member Posts: 24,877 Gold Badge
    Andrea_Giovannini wrote:
    Hi jschell,
    the Java part of the application has no problems with resources (I've checked and double-checked): if we exclude the DLL the only external resource I access is the database and connections are correctly returned to the connection pool (it's a J2EE application running on JBoss).
    That of course cannot be true. File IO would of course be another resource usage in an java app - since it reads jars,etc.
    If I stress a version of the application without DLL integration then OutOfMemoryError is never raised and memory occupation seems stable (this suggests me that there aren't problems with the Java part).
    In a stress test if you lower the maximum allowed heap it can cause resource problems to show up better. Naturally at some point lowering it too much could give false positives.
    If I stress the application with the DLL integration then I get the OutOfMemoryError: I have the impression that the problem is caused by the DLL, but I don't know what to do :-(
    I've found in several answers to the same problem (in different forums) that a possible solution can be reducing the heap size for the JVM but I can't do it: the application starts with 512MB as heap min and max size and this is the minimum in order to obtain good performance for the application.
    Since I don't know what the dll does I can't help you with that. One thing a dll can do is request memory from the OS. So if a dll on start up requests a 1 gig on a machine with an addressable application space of 2 gigs then that means at most the VM will only have 1 gig for itself. You can force this by having java request a lot of space before calling the dll (and loading it) by creating a very big byte array. This is a similar trick to the one above of lowering the maximum memory. The idea of course is to make the dll fail rather than java so you can at least get an idea of what it is doing.

    The other alternative is to remove the dll from the java code entirely. Create a C Executable that wraps the dll. Provide a communications interface (files, stdio or sockets), manage it from the java app via Runtime.exec() and communicate from it with java via the communications interface. Myself this is the first solution I would always attempt since it remove the possibility that the native code will take down your server and it makes debugging a lot easier.
  • 843829
    843829 Member Posts: 49,201
    Hi jschell,
    thank you very much for your answer.
    After a deeper analysis of the DLL C code we've found that in a point it was allocating memory without releasing it after usage: fixing this problem resolved the OutOfMemoryError. Sorry if I excluded your first suggestion about resource problem in my previous post.

    Regards,
    Andrea
This discussion has been closed.