Улучшение исполнения JNA - PullRequest
4 голосов
/ 13 января 2011

У меня есть следующая ситуация на стороне C. У меня есть функция, которая создает и возвращает массив целых чисел, представляющих значения RGB для изображения,


  int* pxs(Image* m){
    int* colors = malloc(height * width * sizeof(int));

    //fill the array

    return colors;
   }

На стороне Java я получаю его, используя


     //invoke
     Pointer ptr = ref.getPointer();
     int pxs[] = pointer.getIntArray(0, width*height);

     //to an image
     Image img = Toolkit.getDefaultToolkit().createImage(new MemoryImageSource(width, height, pxs, 0 ,width)); 

Затем изображение рисуется на панели, из-за того, что я сделал все, что занимает около 50-60 мсек, изображения с камеры, поэтому я получаю новый и рисую в цикле, но через некоторое время10 секунд или около того) моя машина останавливается.Я думаю, это связано со сборкой мусора?так мне было интересно, есть ли способ это исправить?

Ответы [ 3 ]

3 голосов
/ 13 января 2011

Помимо отсутствия свободного места, вы должны принять дополнительные меры предосторожности, так как это в любом случае может привести к проблемам с памятью:

Если вы неоднократно выделяете память из «пространства c» (не кучи), виртуальная машина не чувствуетсбор мусора, потому что пространство кучи не используется.Но DirectByteBuffers освободит выделенное пространство c только в методе finalize -> Это приводит к «утечке» виртуальной памяти.

Вы можете «обойти» это, используя частые вызовы «System.gc» или даже лучше не выделять столько памяти c, например, используя только один буфер передачи.

3 голосов
/ 13 января 2011

Помимо утечки памяти, на которую указывают mtraut и Hamza Yerlikaya , вы также создаете ненужную копию данных пикселей (MemoryImageSource оборачивает массив, нозатем Image выделяет свой собственный буфер и копирует в него исходные пиксели.)

Этого можно избежать, создав BufferedImage, который разделяет массив:

ColorModel cm = ColorModel.getRGBdefault();
DataBuffer buffer = new DataBufferInt(pxs, width * height);
WritableRaster raster =
    Raster.createPackedRaster(buffer, width, height, width,
                              new int[] {0xFF0000, 0xFF00, 0xFF, 0xFF000000},
                              null);
BufferedImage img = new BufferedImage(cm, raster, false, null);
3 голосов
/ 13 января 2011

Вы никогда не free с массивом цветов!Если JNA не делает мажическую, классическую утечку памяти.

Может быть, лучше передать ByteBuffer собственной функции и заставить pxs взять char * для заполнения данными.

...