質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

Q&A

0回答

944閲覧

JNI ERROR (app bug): weak global reference table overflow (max=51200)および弱参照について

shikasama

総合スコア163

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

0グッド

0クリップ

投稿2018/04/24 01:53

編集2018/04/25 00:37

前提・実現したいこと

測定機器とWi-fiで接続し、機器に表示される画像データを繰り返し取得し、ImageViewに表示するアプリを作成しています。

androidアプリのデバッグ中(10分くらい動作させっぱなし)に以下のエラーが発生しました。

JNI ERROR (app bug): weak global reference table overflow (max=51200)

JNIというものを初めて聞いたので調べ、JavaからCのライブラリを呼べる仕組みと認識しました。
個人で書いたコードではJNIを利用した覚えがないのでなぜエラーが起きたかわかりません。
そのため、コードのどこを調べていけばいいかもわかりません。

使用しているライブラリ中でJNIを利用しているとかでしょうか?

弱参照についても今調べていますが、まだわかっていません。
どういうところを疑えばいいか、エラーが起きる原因、解決方法などをご教授ください。

発生している問題・エラーメッセージ

エラーログが長いので外部のテキスト共有サイトを利用します。
エラーログ

該当のソースコード

どの箇所が影響しているかわかりませんでした。

追記
画像データの取得(ソケット通信)でスレッドを立てています。
参考になるかわかりませんが、いかにその部分を抜き出したコードを記載します。

波形データ取得部分

kotlin

1private fun getScreenImage() { 2 isStop = false 3 isTriggerStoped = false 4 5 if(socketControl?.isConnect() == false) { 6 // 未接続 7 return 8 } 9 10 buttonSave.isEnabled = false 11 12 Toast.makeText(applicationContext, getString(R.string.text_image_acquisition_start), Toast.LENGTH_SHORT).show() 13 14 Thread(Runnable { 15 while(!isStop) { 16 Thread.sleep(0) 17 waitForTrgStop() 18 isTriggerStoped = false 19 20 receiveBuff = null 21 22 // 画像転送コマンド送信(受信データはBinary) 23 var str = "(画像転送コマンド)" 24 str += "PNG" 25 26 Thread.sleep(10) 27 socketControl?.sendCommand(str, true) 28 29 var timeout = 500 30 31 while (true) { 32 try { 33 Thread.sleep(80) 34 if(timeout < 0) { 35 break 36 } else if(receiveBuff != null) { 37 imageData = receiveBuff?.copyOf() 38 receiveBuff = null 39 Thread.sleep(10) 40 break 41 } 42 } catch (e: Exception) { 43 e.printStackTrace() 44 } 45 46 timeout -= 100 47 } 48 49 if(timeout < 0) { 50 continue 51 } 52 53 if(!checkBoxContinuousAcquisition.isChecked) { 54 isStop = true 55 } 56 57 class Mythread : Thread() { 58 override fun run() { 59 var bmp : Bitmap? = null 60 var imageSize = 0 61 if(imageData != null) { 62 imageSize = imageData?.size ?: 0 63 bmp = BitmapFactory.decodeByteArray(imageData, 0, imageSize) 64 } 65 66 if(imageSize == 0) { 67 Toast.makeText(applicationContext, getString(R.string.text_imageData_size_0), Toast.LENGTH_SHORT).show() 68 return 69 } 70 71 if(bbmp == null) { 72 Glide.with(applicationContext) 73 .load(bmp) 74 .into(imageViewWaveform) 75 bbmp = bmp 76 } 77 else { 78 requestOptions.placeholder(BitmapDrawable(resources,bmp)) 79 80 Glide.with(applicationContext) 81 .load(bmp) 82 .apply(requestOptions) 83 .into(imageViewWaveform) 84 bbmp = bmp 85 } 86 87 if(isTriggerStoped) { 88 isTriggerStoped = false 89 } 90 } 91 } 92 93 val myRun = Mythread() 94 runOnUiThread(myRun) 95 myRun.join() 96 97 Thread.sleep(1) 98 } 99 100 if(checkBoxContinuousAcquisition.isChecked) { 101 receiveBuff = null 102 103 // 画像転送コマンド送信(受信データはBinary) 104 var str = "(画像転送コマンド) " 105 str += "PNG" 106 107 Thread.sleep(100) 108 socketControl?.sendCommand(str, true) 109 110 while (true) { 111 try { 112 Thread.sleep(100) 113 if(receiveBuff != null) { 114 imageData = receiveBuff?.copyOf() 115 receiveBuff = null 116 Thread.sleep(10) 117 break 118 } 119 } catch (e: Exception) { 120 e.printStackTrace() 121 } 122 } 123 124 class Mythread2 : Thread() { 125 override fun run() { 126 var bmp : Bitmap? = null 127 var imageSize = 0 128 if(imageData != null) { 129 imageSize = imageData?.size ?: 0 130 bmp = BitmapFactory.decodeByteArray(imageData, 0, imageSize) 131 } 132 133 if(imageSize == 0) { 134 Toast.makeText(applicationContext, getString(R.string.text_imageData_size_0), Toast.LENGTH_SHORT).show() 135 return 136 } 137 138 if(bbmp == null) { 139 Glide.with(applicationContext) 140 .load(bmp) 141 .into(imageViewWaveform) 142 bbmp = bmp 143 } 144 else { 145 requestOptions.placeholder(BitmapDrawable(resources,bmp)) 146 147 Glide.with(applicationContext) 148 .load(bmp) 149 .apply(requestOptions) 150 .into(imageViewWaveform) 151 bbmp = bmp 152 } 153 154 155 if(isTriggerStoped) { 156 isTriggerStoped = false 157 } 158 } 159 } 160 161 val myRun2 = Mythread2() 162 runOnUiThread(myRun2) 163 myRun2.join() 164 } 165 166 class Mythread3 : Thread() { 167 override fun run() { 168 buttonGetScreenImage.isEnabled = true 169 buttonSave.isEnabled = true 170 Toast.makeText(applicationContext, getString(R.string.text_image_acquisition_stop), Toast.LENGTH_SHORT).show() 171 } 172 } 173 174 val myRun3 = Mythread3() 175 runOnUiThread(myRun3) 176 myRun3.join() 177 }).start() 178}

ソケット通信でのデータ送信部分

kotlin

1fun sendCommand(sendStr: String, isBinaryReceive: Boolean): Boolean { 2 if (this.socketClient?.isConnect() != true) { 3 // 未接続 4 return false 5 } 6 7 this.isBinary = isBinaryReceive 8 this.receiveBuff = null 9 this.receiveNum = 0 10 val str = sendStr + "\r\n" 11 val data = str.toByteArray(Charsets.UTF_8) 12 this.socketClient?.sendThread(data) 13 14 return true 15} 16 17fun sendThread(data : ByteArray) : Boolean { 18 var result = false 19 this.sendBuff = data 20 try { 21 thread { 22 result = send(sendBuff) 23 }.join() 24 } 25 catch (e : Exception) { 26 Log.d("TCP/IP sendTh", e.toString()) 27 } 28 return result 29} 30 31private fun send(data : ByteArray) : Boolean { 32 var result = false 33 34 try { 35 output?.write(data, 0, data.size) 36 output?.flush() 37 result = true 38 } catch (e : Exception) { 39 Log.e("TCP/IP send", e.toString()) 40 return result 41 } 42 return result 43}

補足情報(FW/ツールのバージョンなど)

Android Studio3.0.1
kotlin 1.2.30

使用しているライブラリなど

  • org.jetbrains.kotlin:kotlin-stdlib-jdk7
  • com.android.support:support-v4:27.1.0
  • com.android.support.constraint:constraint-layout:1.0.2
  • com.android.support:design:27.1.0
  • junit:junit:4.12
  • com.android.support.test🏃‍♂️1.0.1
  • com.android.support.test.espresso:espresso-core:3.0.1
  • com.github.bumptech.glide:glide:4.6.1
  • com.github.bumptech.glide:compiler:4.6.1

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kakajika

2018/04/24 08:43

JNIを直接触られていないのであれば、何らかの原因で解放漏れが起きている可能性が高そうです。エラーログを見ると落ちる直前に大量のthreadのインスタンスが生成されているようですが、これは意図する挙動ですか?
shikasama

2018/04/25 00:40

画像データの取得とImageViewの更新でThreadを立てております。joinで待っているので問題ないかと思っていましたが、誤った認識なのでしょうか?また、デバッグだと再現して、ただの実行だと再現しませんでした。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問