Java application calls C ++ DLL through JNI; what is the best way to allocate memory?

Basic summary of the question: What is the best way to optimize memory allocation in order to provide as much memory as possible for DLLs that I can access through JNI? What should I strive to minimize, what should I strive to maximize, etc.

SYSTEM: Running JBoss 6 as a Windows 32 service on a 32-bit system with 4 GB of RAM. I understand that there are maximum memory limits for a Java heap. JVM JRE1.6.0_26

SERVICE: Installed under JBoss - this is a webapp that receives requests from clients; each request calls a C ++ - built DLL through JNI to process the image file in any way.

QUESTION: Sometimes, when large or some (not all) LZW-compression images, the calling java class receives a message stating that the DLL is experiencing global memory depletion and has not completed the requested process.

There are no more active operations on the underlying Windows processes on the server.

The current JBOSS application server memory settings are as follows, but may be excessive:

-Xms1024m -Xmx1024m -Xss1024k -XX: MaxPermSize = 128 m

I am trying to determine the best memory options to provide as many resources for the JNI DLL as I understand it, JNI does not use the memory allocated for the Java heap.

I read them, but did not find them useful to answer my question:

Java JNI: memory allocation / partitioning

Is it possible to use jconsole to identify memory leaks in C ++ JNI objects?

The two answers currently provided do not address an inherent issue.

Current JBoss server memory in a week with the JVM parameters specified above (TaskManager points the java.exe process to 750,672k)

Total Memory Pools: 5 Pool: Code Cache (Non-heap memory) Peak Usage : init:2359296, used:7317312, committed:7438336, max:50331648 Current Usage : init:2359296, used:7306496, committed:7438336, max:50331648 |---------| committed:7.09Mb +---------------------------------------------------------------------+ |/////////| | max:48Mb +---------------------------------------------------------------------+ |---------| used:6.97Mb Pool: PS Eden Space (Heap memory) Peak Usage : init:268500992, used:354811904, committed:354811904, max:355991552 Current Usage : init:268500992, used:270153472, committed:354091008, max:354156544 |--------------------------------------------------------------------| committed:337.69Mb +---------------------------------------------------------------------+ |///////////////////////////////////////////////////// || max:337.75Mb +---------------------------------------------------------------------+ |----------------------------------------------------| used:257.64Mb Pool: PS Survivor Space (Heap memory) Peak Usage : init:44695552, used:44694896, committed:78643200, max:78643200 Current Usage : init:44695552, used:0, committed:1835008, max:1835008 |---------------------------------------------------------------------| committed:1.75Mb +---------------------------------------------------------------------+ | | max:1.75Mb +---------------------------------------------------------------------+ | used:0b Pool: PS Old Gen (Heap memory) Peak Usage : init:715849728, used:123671968, committed:715849728, max:715849728 Current Usage : init:715849728, used:104048648, committed:715849728, max:715849728 |---------------------------------------------------------------------| committed:682.69Mb +---------------------------------------------------------------------+ |////////// | max:682.69Mb +---------------------------------------------------------------------+ |---------| used:99.23Mb Pool: PS Perm Gen (Non-heap memory) Peak Usage : init:16777216, used:91989664, committed:134217728, max:134217728 Current Usage : init:16777216, used:90956472, committed:90963968, max:134217728 |----------------------------------------------| committed:86.75Mb +---------------------------------------------------------------------+ |//////////////////////////////////////////////| | max:128Mb +---------------------------------------------------------------------+ |----------------------------------------------| used:86.74Mb 
+7
source share
1 answer

Memory allocated by native code wrapped in JNI is allocated to the JVM process, but is not under the control of your Java code. It is not part of the heap and is not configured using JVM options. Basically, everything that is highlighted using native malloc should be managed by this native code. If you control the libraries that you use, you need to go through it and check for resource leaks. This is especially important if it is used in a long-lasting process.

In my experience, the best approach would be to examine your actual memory usage by pulling on the JMX statistics exposed by the JVM. Once you have an idea of ​​how much memory your Java application consumes, you will better understand where to set the maximum heap settings. The Permgen scope is used to define classes, etc., so you really don't need a lot of memory there unless you are doing a bunch of loading of a dynamic class.

Until you can tune the memory available for the JNI library, tune the memory reserved for your heap, and thus potentially free up resources for use by the library.

As you would expect, adding a heap of memory reaches a maximum of about 1022.19 (the maximum size of your heap). When the heap is exhausted, the full GC cycle begins, and the dirty heap is restored. Based on the numbers you provided, I suggest starting with Xmx512m. This will give your JNI code number a breath.

If you find that the JVM gets bogged down due to excessive garbage collection, it means that you have run out of a bunch of Java too quickly, you can increase this distribution. However, if he eats 512 MB fast enough to cause a noticeable effect on performance, it is unlikely that anything other than a significant increase will have a big effect. It all depends to a large extent on your program, on how fast it eats a bunch of Java and how efficient the full GC operation is.

+10
source

All Articles