我有这个代码在Java和内存在ram几乎爆炸在短短几秒钟。我发布IplImage"imagensMedia"。为什么? ?
编辑:这个函数每秒运行多次
int largura=1280;
int altura=800;
IplImage[] imagens = new IplImage[5];
IplImage imagensSoma=cvCreateImage(cvSize(largura,altura), 32, 3);
int indiceImagem=0;
for(x=0; x<imagens.length;x++)
imagens[x]=cvCreateImage(cvSize(largura,altura), 8, 3);
public void imageArrayBuilder() //Constroi Array de Imagens e a Sua Media
{
int z;
IplImage imagensMedia =cvCreateImage(cvSize(largura,altura), 8, 3);
cam.read();
opencv.copy(cam.get());
if(imagemTotalFlag)
{
cvSub(imagensSoma,imagens[indiceImagem],imagensSoma, null);
cvAcc(opencv.Buffer, imagensSoma, null);
cvConvertScale(imagensSoma, imagensMedia, 1.0/imagens.length,0);
cvCopy(opencv.Buffer,imagens[indiceImagem],null);
indiceImagem++;
if(indiceImagem==imagens.length)
indiceImagem=0;
opencv.copy(imagensMedia);
}
else
{
if(indiceImagem<imagens.length)
{
cvCopy(opencv.Buffer,imagens[indiceImagem],null);
indiceImagem++;
if(indiceImagem==imagens.length)
{
imagemTotalFlag=true;
for(z = 0; z < imagens.length; z++)
cvAcc(imagens[z], imagensSoma, null);
cvConvertScale(imagensSoma, imagensMedia, 1.0/imagens.length,0);
indiceImagem=0;
opencv.copy(imagensMedia);
}
}
}
cvReleaseImage(imagensMedia);
}
我不认为"内存泄漏"的概念真正适用于java,因为它是一种垃圾收集语言(当没有其他对象引用它们时,引用会自动删除)。注释给出了一些关于内存被使用的可能性;我建议研究一下垃圾收集是如何工作的(初学者请参阅此链接)。如果所有这些都失败,调用System.gc()
将运行垃圾收集器,或者更具体地说:
调用gc方法表明Java虚拟机花费精力来回收未使用的对象,以便使它们当前占用的内存可以快速重用。当控制从方法调用返回时,Java虚拟机已经尽最大努力从所有丢弃的对象中回收空间。
除此之外,检查无限循环或无限递归。
据我所知,OpenCV的Mat
的Java包装器占用空间很小。底层的本机对象可能正在使用千兆字节的内存(在我的例子中就是这样),而GC对此一无所知。
只有两个选项:
- 使用
Mat.release()
手动释放本机内存 每隔一段时间调用
System.gc()
来强制未引用的Mat
包装器对象的垃圾收集。注意,如果你正在使用VideoCapture
这样的东西来读取帧,你绝对不希望每读取一帧都调用System.gc()
,因为这会破坏性能。我在应用程序中大约每20秒调用一次。