我想知道如何找到内存泄漏,因为我正在制作一个程序,它有一个我想要解决的程序,使用的内存增加得非常快,我需要解决这个问题。
我正在开发的程序是 OpenCv 使用 Javacv 1.1 和 JavaCPP 库从网络摄像头进行人脸检测。
private IplImage detectFace(IplImage image, CvScalar color) {
int number = 3;
IplImage imageGray = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);
cvCvtColor(image, imageGray, CV_BGR2GRAY);
IplImage smallImg = IplImage.create(imageGray.width()/2, imageGray.height()/2, IPL_DEPTH_8U, 1);
cvResize(imageGray, smallImg, CV_INTER_LINEAR);
cvEqualizeHist(smallImg, smallImg);
CvMemStorage storage = CvMemStorage.create();
if(faceDetector.isNull())
faceDetector = new CvHaarClassifierCascade(cvLoad(dataBase+"\\haarcascade_frontalface_alt.xml"));
CvSeq faces = cvHaarDetectObjects(smallImg, faceDetector, storage, 1.3, number, CV_HAAR_DO_CANNY_PRUNING);
cvClearMemStorage(storage);
int total = faces.total();
for (int i = 0; i < total; i++) {
CvRect r = new CvRect(cvGetSeqElem(faces, i));
cvRectangle(image, cvPoint( r.x()*2, r.y()*2 ),cvPoint( (r.x() + r.width())*2,(r.y() + r.height())*2 ), color, 2, CV_AA, 0);
}
return image;
}//end of face detection
上面的方法就是发现内存泄漏的地方。
好吧,泄漏已经大大减少了,但是仍然有一个开始很小的泄漏,随着时间的推移,每秒增加的内存量增加了,通过相机捕获视频的方法如下:
在 detectFace 方法中,释放 IplImage 的内存:imageGray和smallImg,我不知道增加是否是由于它返回的参数的 IplImage 变量。但是当我从循环中删除 detectFace 方法时,内存使用保持稳定。所以还是有漏
除了检测会消耗大约 30% 的 cpu 之外,视频捕获也会随着时间的推移一点一点地增加内存。
现在,我猜(我没有使用 OPenCV)是缺少释放内存的
IplImage
:缺少一个:
另请查看调用此方法的代码,即创建作为参数传递给它的图像的代码,也应该在停止使用图像时进行释放。
要检测内存泄漏,您可以使用许多工具,但它需要一个稍微更有条理的过程。例如看看这篇文章:
https://www.toptal.com/java/hunting-memory-leaks-in-java
它提到了几个技巧,包括:
-verbosegc
。通过这些技巧,您将能够检测 Java 应用程序中的内存泄漏,无论您是否使用 OpenCV,它们都会以通用的方式对您有用,并且您不会盲目地尝试查看错误在哪里。