bytedeco/javacv

JavaCV in Kotlin - Memory Allocation/Management?

Open

#1,975 opened on 2023年1月22日

GitHub で見る
 (7 comments) (0 reactions) (0 assignees)Java (1,583 forks)batch import
enhancementhelp wanted

Repository metrics

Stars
 (6,985 stars)
PR merge metrics
 (30d に merged PR はありません)

説明

I'm building an app in Kotlin that heavily depends on image processing through saliency.

My code looks like this:

package com.example.testingsaliency5

import android.graphics.Bitmap
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.core.graphics.drawable.toBitmap
import com.example.testingsaliency5.databinding.ActivityMainBinding
import org.bytedeco.javacv.AndroidFrameConverter
import org.bytedeco.javacv.OpenCVFrameConverter.ToMat
import org.bytedeco.opencv.opencv_core.Mat
import org.bytedeco.opencv.opencv_saliency.StaticSaliencyFineGrained


class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        val view = binding.root
        binding.imageView.setImageDrawable(this.resources.getDrawable(R.drawable.lancer))
        binding.button.setOnClickListener { binding.imageView.setImageBitmap(saliencyBitmap(binding.imageView.drawable.toBitmap())) }
        setContentView(view)
    }

    fun saliencyBitmap(bitmap : Bitmap) : Bitmap {

        val converterToBitmap = AndroidFrameConverter()
        val converterToMat = ToMat()

        val frame = converterToBitmap.convert(bitmap)
        val saliencyMap = Mat()
        val byteMap = Mat()
        val sal = StaticSaliencyFineGrained()
        sal.computeSaliency(converterToMat.convert(frame), saliencyMap)
        sal.computeBinaryMap(saliencyMap, byteMap)

        return converterToBitmap.convert(converterToMat.convert(byteMap))
    }
}

But when ran, after I press the button, I get this error on line return converterToBitmap.convert(converterToMat.convert(byteMap)):

I/estingsaliency5: Starting a blocking GC Alloc
I/estingsaliency5: Starting a blocking GC Alloc
I/estingsaliency5: Alloc young concurrent copying GC freed 190867(12MB) AllocSpace objects, 0(0B) LOS objects, 86% free, 3863KB/27MB, paused 29us,12us total 22.231ms
I/estingsaliency5: WaitForGcToComplete blocked NativeAlloc on Alloc for 22.376ms
I/estingsaliency5: Forcing collection of SoftReferences for 254MB allocation
I/estingsaliency5: Starting a blocking GC Alloc
I/estingsaliency5: Alloc concurrent copying GC freed 1873(61KB) AllocSpace objects, 0(0B) LOS objects, 86% free, 3817KB/27MB, paused 20us,13us total 9.242ms
W/estingsaliency5: Throwing OutOfMemoryError "Failed to allocate a 266501312 byte allocation with 25165824 free bytes and 252MB until OOM, target footprint 29075352, growth limit 268435456" (VmSize 16893380 kB)
I/estingsaliency5: Starting a blocking GC Alloc
I/estingsaliency5: Starting a blocking GC Alloc
I/estingsaliency5: Forcing collection of SoftReferences for 254MB allocation
I/estingsaliency5: Starting a blocking GC Alloc
I/estingsaliency5: Alloc concurrent copying GC freed 1774(71KB) AllocSpace objects, 0(0B) LOS objects, 86% free, 3746KB/27MB, paused 17us,14us total 8.149ms
W/estingsaliency5: Throwing OutOfMemoryError "Failed to allocate a 266501312 byte allocation with 25165824 free bytes and 252MB until OOM, target footprint 29002392, growth limit 268435456" (VmSize 16893380 kB)
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.testingsaliency5, PID: 4452
    java.lang.OutOfMemoryError: Failed to allocate a 266501312 byte allocation with 25165824 free bytes and 252MB until OOM, target footprint 29002392, growth limit 268435456
        at java.nio.HeapByteBuffer.<init>(HeapByteBuffer.java:54)
        at java.nio.HeapByteBuffer.<init>(HeapByteBuffer.java:49)
        at java.nio.ByteBuffer.allocate(ByteBuffer.java:284)
        at org.bytedeco.javacv.AndroidFrameConverter.gray2rgba(AndroidFrameConverter.java:131)
        at org.bytedeco.javacv.AndroidFrameConverter.convert(AndroidFrameConverter.java:201)
        at com.example.testingsaliency5.MainActivity.saliencyBitmap(MainActivity.kt:38)
        at com.example.testingsaliency5.MainActivity.onCreate$lambda$0(MainActivity.kt:22)
        at com.example.testingsaliency5.MainActivity.$r8$lambda$71u2Lpx-hlCZ4uuH3x2VT4aZAZY(Unknown Source:0)
        at com.example.testingsaliency5.MainActivity$$ExternalSyntheticLambda0.onClick(Unknown Source:2)
        at android.view.View.performClick(View.java:7506)
        at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1219)
        at android.view.View.performClickInternal(View.java:7483)
        at android.view.View.-$$Nest$mperformClickInternal(Unknown Source:0)
        at android.view.View$PerformClick.run(View.java:29341)
        at android.os.Handler.handleCallback(Handler.java:942)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loopOnce(Looper.java:201)
        at android.os.Looper.loop(Looper.java:288)
        at android.app.ActivityThread.main(ActivityThread.java:7872)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
I/Process: Sending signal. PID: 4452 SIG: 9

The quesiton is, do I need to manage memory in some way, when working with JavaCV on Android?

コントリビューターガイド