JAVA、JNI和C应用程序的内存占用问题

JAVA、JNI和C应用程序的内存占用问题,java,c,memory,java-native-interface,Java,C,Memory,Java Native Interface,我有一个用C编写的应用程序,它生成一个JVM,并使用JNI与Java应用程序交互。通过Process Explorer,我的内存占用高达1GB,内存不足。现在据我所知,它应该能够达到2GB。我相信,JVM使用的内存在Process Explorer中是不可见的。我的xmx设置为256,我添加了一些语句来观察java端的内存,它在256处达到峰值,GC正在完成它的工作,这方面一切都很好。所以我的问题是,其他700+MB在哪里被消耗?有谁是Java/JNI/C内存专家吗 编写一个C测试工具,并使用v

我有一个用C编写的应用程序,它生成一个JVM,并使用JNI与Java应用程序交互。通过Process Explorer,我的内存占用高达1GB,内存不足。现在据我所知,它应该能够达到2GB。我相信,JVM使用的内存在Process Explorer中是不可见的。我的xmx设置为256,我添加了一些语句来观察java端的内存,它在256处达到峰值,GC正在完成它的工作,这方面一切都很好。所以我的问题是,其他700+MB在哪里被消耗?有谁是Java/JNI/C内存专家吗

编写一个C测试工具,并使用valgrind/alleyoop检查C代码中的泄漏,同样也可以使用java jvisualvm工具。

C和JNI代码也可以分配内存(malloc/free/new/etc),这在VM的256m之外。xMX只限制VM将分配给自己的内容。取决于您在C代码中分配的内容,以及内存中加载的其他内容,您可能无法获得2GB的内存。

如果您说是Windows进程而不是JVM耗尽了内存,那么我的初步猜测是您可能调用了一些(您自己的)来自JVM的本机方法和那些本机方法泄漏内存。因此,我同意@John Gardner的观点。

JNI代码中可能存在漏洞

记住,一旦使用完对象引用,就要对它们使用(*jni)->DeleteLocalRef()。如果使用任何本机C缓冲区创建新的Java对象,请确保在创建对象后将其释放。查看JNI规范以了解更多指南


根据您正在使用的VM,您可能能够启用JNI检查。例如,在IBMJDK上,您可以指定“-Xcheck:jni”。

尝试一个C语言的测试应用程序,它不会生成JVM,而是尝试分配越来越多的内存。看看测试应用程序是否能达到2GB的标准。

多亏了您的帮助,尤其是@alexander,我发现Java堆正在使用所有通过Process Explorer看不到的额外内存。事实上,通过我运行的其他测试,JVM的内存消耗包含在我从Process Explorer看到的内容中。因此,堆占用了大量内存,我必须对此做更多的研究,也许还需要问一个单独的问题。

是JVM耗尽了内存还是Windows进程?事实上,Java端的内存是空闲的,当C端耗尽时,只有大约60MB。好吧,据我所知,C端的内存是1GB,JVM使用256MB,因此1024+256=1280。我希望能够使用768更多。如果768MB没有在C端使用,也没有被JVM使用,那么消耗的768MB在哪里呢。我还让它在启动JVM之前分配1.4GB,而在尝试启动JVM时,它无法为HEAP对象分配足够的内存。因此,我得出的结论是,堆占用了看不见的内存。那么,检查有多少内存用于映射JVM和C应用程序使用的所有动态库。也许是这段记忆造成的。