Мне нужно создать долго работающее приложение для непрерывной съемки изображений с ограниченными ресурсами (не более 200 МБ ОЗУ). Когда я интегрировал opencv со своим кодом, я увидел непрерывное увеличение использования памяти (начинается с 100 МБ и до 220 МБ, прежде чем я убил его).
Чтобы исправить это, я сделал две вещи:
- Следовал https://github.com/sgjava/opencvmem, чтобы завершить вызовы и внес изменения, предложенные в ссылке.
- Начинает вызывать system.gc () после каждых 120 кликов. (Несколько ответов предлагали это в утечка памяти при итерации кадров Opencv )
После этих изменений использование памяти начинается с 100 МБ и достигает 184 МБ. Есть постепенное увеличение.
Мой тестовый код :
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.videoio.VideoCapture;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.IOException;
import java.util.Date;
public class HelloCV {
private Mat matrix = new Mat();
private BufferedImage image;
private VideoCapture capture;
private long totalTimeTaken = 0;
private long timeTaken = 0;
private long startTime = 0;
private int imagesClicked =0;
public HelloCV (VideoCapture capture) {
this.capture = capture;
this.capture.set(3, 1280);
this.capture.set(4, 720);
this.capture.set(10,50);
for(int i = 1; i <= 15; i++) {
System.out.println("Property ID " + i + " value: " + capture.get(i));
}
}
public static void main(String[] args) {
try {
// Loading the OpenCV core library
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
System.out.println("Loaded libraries . . .");
// Instantiating the VideoCapture class (camera:: -1)
HelloCV cv = new HelloCV(new VideoCapture(-1));
System.out.println("Camera open: " + cv.capture.isOpened());
int count = 0;
while(true) {
cv.captureSnapShot();
cv.saveImage();
count++;
cv.imagesClicked++;
System.out.println("Number of images clicked: " + cv.imagesClicked);
if(count >= 120) {
System.gc();
count = 0;
System.out.println("Provided a signal to JVM to run GC. Time: " + new Date().toString());
}
Thread.sleep(1000);
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void captureSnapShot() {
startTime = System.currentTimeMillis();
// Reading the next video frame from the camera
capture.read(matrix);
// If camera is opened
if (capture.isOpened()) {
System.out.println("Camera is open . . .");
// If there is next video frame
if (capture.read(matrix)) {
timeTaken = System.currentTimeMillis() - startTime;
System.out.println("Next video frame available . . .");
System.out.println("Click Image Latency : " + timeTaken + " milliseconds.");
// Creating BufferedImage from the matrix
image = new BufferedImage(matrix.width(),
matrix.height(), BufferedImage.TYPE_3BYTE_BGR);
WritableRaster raster = image.getRaster();
DataBufferByte dataBuffer = (DataBufferByte) raster.getDataBuffer();
byte[] data = dataBuffer.getData();
matrix.get(0, 0, data);
}
}
matrix.release();
}
private void saveImage() {
// Saving the Image
String imageName = "sample-" + Long.toString(System.currentTimeMillis()) + ".jpg";
try {
ImageIO.write(image, "JPG", new File(imageName));
totalTimeTaken = System.currentTimeMillis() - startTime;
System.out.println("Click and save Image Latency : " + totalTimeTaken + " milliseconds.");
} catch (IOException e) {
e.printStackTrace();
}
}
}
Не могли бы вы, ребята, помочь мне в определении какой-либо оптимизации в моем коде или предложить способы избавления от постоянного увеличения использования памяти? Заранее спасибо.