【发布时间】:2016-12-05 11:40:59
【问题描述】:
我遇到了一个 JNI 程序随机耗尽内存的问题。
这是一个 32 位 java 程序,它读取文件,进行一些图像处理,通常使用 250MB 到 1GB。然后丢弃所有这些对象,然后程序对通常需要 100-250MB 的 JNI 程序进行一系列调用。
当交互式运行时,我从未见过问题。但是,当对多个文件连续执行批处理操作时,JNI 程序将随机耗尽内存。它可能有一个或两个文件的内存问题,然后在接下来的 10 个文件中运行良好,然后再次出现故障。
我已经在 JNI 调用之前转储了可用内存量,它遍布整个地图,有时是 100MB,有时是 800MB。我的解释是,Java 垃圾收集有时会在图像处理后立即运行,有时则不会。如果不是,则可能没有足够的内存供 JNI 程序使用。
我已经阅读了所有关于 GC 是不确定的、不应该调用它、不会产生任何影响等的内容,但似乎在开始 JNI 调用之前强制 GC 会改善这种情况。
但是有什么方法可以真正确保在继续之前有一定数量的空闲内存?
要回答有关 JNI 程序的问题,该程序由另一家公司提供,我对它如何分配内存没有真正的了解。我所知道的是它是用 c++ 编写的,它没有垃圾收集。有人告诉我它需要 100-250MB 的内存,而我看到的数字可以证实这一点。
也许我应该将问题改写为:如果我要进行一个我知道需要 250MB 内存的 JNI 调用,我如何确保它有那么多可用内存?
确实,一种可能的解决方案是进行 64 位构建。但是,这个批处理操作是 32 位构建的 QA 的一部分,所以我想测试真实的东西。
【问题讨论】:
-
您没有向我们展示任何代码。这就像让您的医生通过电话诊断您的间歇性疼痛,甚至没有告诉她疼痛在哪里。请访问help center 并阅读How to Ask。
-
增加最大堆大小是一种选择吗?
-
@JimGarrison 不一定。他很好地描述了这个问题,以至于代码在一般情况下不会带来太多(即如果他没有在他的代码中做疯狂的事情)。这是关于 JNI 调用期间 GC 和内存使用的一般问题。我无法回答,但我仍然认为这个问题很好
-
我认为至少需要更多关于 JNI 代码在做什么的细节,尤其是它如何分配内存。 GC 是一个非常困难的话题,具体案例的信息越多越好。
-
问:“可用内存量”到底是什么意思?问:究竟什么是“内存不足”——JRE,还是你的操作系统? Java堆,还是“别的东西”?问:您的操作系统是什么是?您的 JRE 版本?
标签: java garbage-collection java-native-interface