bytedeco/javacv

JavaCV in Kotlin - Memory Allocation/Management?

Open

#1,975 创建于 2023年1月22日

在 GitHub 查看
 (7 评论) (0 反应) (0 负责人)Java (1,583 fork)batch import
enhancementhelp wanted

仓库指标

Star
 (6,985 star)
PR 合并指标
 (30 天内没有已合并 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?

贡献者指南