简体   繁体   English

Java应用程序通过JNI调用C ++ DLL; 如何最好地分配内存?

[英]Java app calls C++ DLL via JNI; how best to allocate memory?

Basic summary of question is: How do I best optimize my memory allocation to give as much memory to the DLLs I access through JNI as possible? 问题的基本摘要是:如何最好地优化我的内存分配,以便为我通过JNI访问的DLL提供尽可能多的内存? What should I aim to minimize, what should I aim to maximize, etc. 我应该尽量减少什么,我应该最大化什么,等等。

SYSTEM: Running JBoss 6 as a Windows 32 Service in a 32-bit system with 4 GB RAM. SYSTEM:在具有4 GB RAM的32位系统中将JBoss 6作为Windows 32服务运行。 I do understand there are maximum restrictions on memory for Java Heap. 我确实理解Java Heap的内存有最大限制。 JVM is JRE1.6.0_26 JVM是JRE1.6.0_26

SERVICE: Installed under JBoss is a webapp which receives requests from clients; 服务:安装在JBoss下的是一个接收客户请求的webapp; each request calls the C++-built DLL through JNI to process an image file in some fashion or other. 每个请求通过JNI调用C ++构建的DLL来以某种方式处理图像文件。

ISSUE: Occasionally, with larger or some (not all) LZW-compression images, the calling java class receives a message that the DLL experienced a Global Memory Depletion and failed to complete the requested process. 问题:有时,对于较大的或一些(并非所有)LZW压缩映像,调用java类会收到DLL遇到全局内存耗尽并且无法完成请求的进程的消息。

There is nothing else actively running on the server beyond basic windows processes. 除了基本的Windows进程之外,服务器上没有任何其他活动。

Current JBOSS App Server memory settings are as follows, but may be excessive: 当前的JBOSS App Server内存设置如下,但可能过多:

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

I am trying to determine the best memory settings to give as much resources to the JNI DLL, as I understand JNI does not use any memory allocated to the Java Heap. 我正在尝试确定最佳内存设置,以便为JNI DLL提供尽可能多的资源,因为据我所知,JNI不使用分配给Java堆的任何内存。

I have read these, but did not find them helpful to answer my question: 我已阅读这些内容,但没有发现它们对回答我的问题有帮助:

Java JNI : Memory allocation / partitioning Java JNI:内存分配/分区

Can jconsole be used to identify memory leaks in JNI C++ objects? 可以使用jconsole来识别JNI C ++对象中的内存泄漏吗?

The two answers currently supplied do not address the inherient question. 目前提供的两个答案没有解决遗留问题。

Current memory of JBoss server after one week with JVM params set as above (TaskManager indicates java.exe process at 750,672k) 一周后JBoss服务器的当前内存与JVM参数设置如上(TaskManager指示java.exe进程为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

Memory allocated by the native code wrapped by JNI is allocated to the JVM process, but is not under the control of your Java code. 由JNI包装的本机代码分配的内存分配给JVM进程,但不受Java代码的控制。 It is not part of the heap, and is not tunable via JVM parameters. 它不是堆的一部分,并且不能通过JVM参数进行调整。 Basically, anything allocated with a native malloc must be managed by that native code. 基本上,使用本机malloc分配的任何内容都必须由该本机代码管理。 If you are in control of the libraries you are using, its imperative that you go through it and check for resource leaks. 如果您掌控所使用的库,则必须通过它并检查资源是否泄漏。 This is especially important if this is being used in a long lived process. 如果在长期使用过程中使用它,这一点尤为重要。

In my experience the best approach would be to examine your actual memory use by pulling the JMX stats exposed by the JVM. 根据我的经验,最好的方法是通过拉动JVM公开的JMX统计数据来检查实际的内存使用情况。 Once you have an idea about how much memory your Java app consumes You'll have a better idea about where to set your max heap settings. 一旦您了解了Java应用程序消耗了多少内存,您就可以更好地了解设置最大堆设置的位置。 Permgen space is used for class definitions and such, so you really shouldn't need much memory there unless you are doing a bunch of dynamic class loading. Permgen空间用于类定义等,所以除非你正在做一堆动态类加载,否则你真的不需要太多内存。

While you cannot tune the memory available for the JNI library, tuning the memory reserved for your heap and such will potentially free up resources for use by the library. 虽然您无法调整可用于JNI库的内存,但调整为堆保留的内存等可能会释放资源以供库使用。

As would be expected, adding the heap memory peaks together it comes out to about 1022.19 (the max size of your heap). 正如所预料的那样,将堆内存峰值加在一起就会出现大约1022.19(堆的最大大小)。 When the heap is exhausted a full GC run is kicked off and dirty heap is reclaimed. 当堆耗尽时,将启动完整的GC运行并回收脏堆。 Based on the numbers that you have provided, I'd suggest starting with a Xmx512m. 根据您提供的数字,我建议从Xmx512m开始。 This will give your JNI code room to breath. 这将为您的JNI代码室提供呼吸。

If you find that the JVM is thrashing due to excessive garbage collection, meaning that you're running out of Java heap too quickly, you could grow that allocation. 如果您发现JVM由于过多的垃圾收集而发生颠簸,这意味着您的Java堆耗尽过快,您可以增加该分配。 However, if it is eating up 512mb rapidly enough to cause a noticeable performance impact, its unlikely that anything short of a significant increase will have much effect. 但是,如果它足够快地消耗512mb以引起明显的性能影响,那么任何不显着增加的东西都不会产生太大影响。 This all depends heavily on your program, how quickly it eats the Java heap, and how effective the full GC run is. 这一切都在很大程度上取决于您的程序,它吃Java堆的速度以及完整GC运行的效率。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM