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

时间:2020-03-06 14:27:18  来源:igfitidea点击:

我有一个用C编写的应用程序,它产生一个JVM并使用JNI与Jav​​a应用程序进行交互。我通过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检查。例如,在IBM JDK上,我们可以指定" -Xcheck:jni"。

在C语言中尝试一个不会生成JVM而是尝试分配越来越多的内存的测试应用程序。查看测试应用程序是否可以达到2 GB的限制。

好了,感谢所有帮助,尤其是@alexander,我发现Java堆正在使用通过Process Explorer无法看到的所有额外内存。实际上,通过我已经运行的其他测试,JVM的内存消耗包含在我从Process Explorer中看到的内容中。因此,堆占用了大量内存,我将不得不对此进行更多研究,并可能提出一个单独的问题。