Постоянное увеличение использования памяти в долго работающем Java-приложении, которое использует openCV для съемки изображений. - PullRequest
0 голосов
/ 02 января 2019

Мне нужно создать долго работающее приложение для непрерывной съемки изображений с ограниченными ресурсами (не более 200 МБ ОЗУ). Когда я интегрировал opencv со своим кодом, я увидел непрерывное увеличение использования памяти (начинается с 100 МБ и до 220 МБ, прежде чем я убил его).

Чтобы исправить это, я сделал две вещи:

  1. Следовал https://github.com/sgjava/opencvmem, чтобы завершить вызовы и внес изменения, предложенные в ссылке.
  2. Начинает вызывать 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();
        }
    }
}

Не могли бы вы, ребята, помочь мне в определении какой-либо оптимизации в моем коде или предложить способы избавления от постоянного увеличения использования памяти? Заранее спасибо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...