如何显式释放Java/Android中本机代码使用的内存
我在Android项目中使用DL4J运行CNN网络作为分类器。问题是,这个CNN模型占用的内存超过了我的智能手机允许的每个应用程序堆大小,从而导致内存不足错误。因此,我想知道是否有一种方法可以显式释放本机DL4J代码分配的内存 我的输入总共是200个图像补丁。我需要将它们堆叠在一起,以便处理时间更快。我尝试将批处理大小设置为32,以便每个输入数组的大小为[32,3,44,44]。我也试了16、8等等。。但我唯一没有内存溢出错误的时间是每次输入一个图像补丁。但我负担不起这么长的处理时间 我试图用GC显式释放内存,但没有成功,这是有道理的,因为内存是由本机代码占用的如何显式释放Java/Android中本机代码使用的内存,java,android,dl4j,Java,Android,Dl4j,我在Android项目中使用DL4J运行CNN网络作为分类器。问题是,这个CNN模型占用的内存超过了我的智能手机允许的每个应用程序堆大小,从而导致内存不足错误。因此,我想知道是否有一种方法可以显式释放本机DL4J代码分配的内存 我的输入总共是200个图像补丁。我需要将它们堆叠在一起,以便处理时间更快。我尝试将批处理大小设置为32,以便每个输入数组的大小为[32,3,44,44]。我也试了16、8等等。。但我唯一没有内存溢出错误的时间是每次输入一个图像补丁。但我负担不起这么长的处理时间 我试图
for (int i = 0; i < N / UtilsCustom.NN_batch_size; i++) {
INDArray temp = UtilsCustom.overallArray.get(NDArrayIndex.interval(i * UtilsCustom.NN_batch_size, i * UtilsCustom.NN_batch_size + UtilsCustom.NN_batch_size), NDArrayIndex.all(), NDArrayIndex.all(), NDArrayIndex.all());
NN_classify(temp);
a = i * UtilsCustom.NN_batch_size + UtilsCustom.NN_batch_size;
if (i%2==1){
model = null;
java.lang.System.gc();
Log.d(TAG, "GCGCGC");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
loadNNModel();
}
temp = null;
java.lang.System.gc();
}
private void NN_classify(INDArray imageMat) {
int result;
DataNormalization scaler = new ImagePreProcessingScaler(0, 1);
scaler.transform(imageMat);
INDArray output = model.output(imageMat);
Log.d(LOG_TAG, "output.size(): " + output.size(0) + ", " + output.size(1));
double prob_parasitemic = 0, prob_uninfected = 0;
for (int i = 0; i < output.size(0); i++) {
prob_parasitemic = output.getDouble(i, 0);
prob_uninfected = output.getDouble(i, 1);
Log.d(LOG_TAG, "prob_parasitemic: " + i + " " + output.getDouble(0, 0));
Log.d(LOG_TAG, "prob_uninfected: " + i + " " + output.getDouble(0, 1));
}
if (prob_parasitemic > prob_uninfected) {
result = 2;
} else {
result = 1;
}
Log.e(LOG_TAG, "Result: " + result);
imageMat = null;
output = null;
java.lang.System.gc();
}
for(int i=0;iprob_未受感染){
结果=2;
}否则{
结果=1;
}
Log.e(Log_标签,“Result:+Result”);
imageMat=null;
输出=空;
java.lang.System.gc();
}
java.lang.System.gc()
不会做您认为它会做的事情。在C中,它不像C中的自由,也不是C++中的删除。p>
对JVM来说,运行垃圾收集更像是一种“建议”。它不强制垃圾收集或释放内存
请参阅:
它说
我不会在你的代码中依赖它。如果JVM即将抛出OutOfMemoryError,那么调用System.gc()不会阻止它,因为垃圾收集器会在达到极限之前尝试释放尽可能多的垃圾
实际上,它可能只需要那么多内存。尝试将批处理设置为1项,查看它使用了多少内存。如果它使用X内存,而您没有足够的内存存储2X,则您无法在逻辑上将另一项放入批处理中。也许应该将训练数据发送到服务(可以缩放),然后将学习的模型返回到设备。