■Androidで大きいサイズのビットマップを扱うその2
以前、Androidで大きいサイズのビットマップを扱う際にBitmap.recycle()を呼び出さないとだめだとエントリー記述しました。
あれから数ヶ月がたち再びビットマップで問題が発生し、もう少し詳しい知識が付いたので再び取り扱います。
まず、Androidでは扱うヒープにいくつか種類がありDalvikヒープとネィティブヒープがあるらしいという点が重要になります。
Bitmapで画像を取り扱う場合、BitmapクラスのオブジェクトはDalvikヒープにメモリを確保しますが、Bitmapデーターの本体はネィティブヒープに領域を確保しこちらはDalvikVMの管理外となります。
そのため何が起きるかというと
Bitmapオブジェクトにnullを詰めてGCが走ってもオブジェクトは解放されるがBitmap画像そのもののデーターはネィティブヒープを確保したまま残ってしまうという事のようです。
そして今回はまったのはgalaxyやgalaxy tabでは読み込めるサイズのBitmapなのに2.1から2.2にアップデートしたDesireではOut of memoryが発生するという現象が起きました。
コチラも調べたところ、どうもforoyo以前にリリースされた端末ではアプリ毎にネィティブヒープを割り当てる制限があるらしいということ。
24MBとも16MBとも言われていましたが。。。よく分からない・・・
という事でためしにいつ落ちるかやってみた!!
adbで以下のコマンドを実行するとメモリの状況が把握できます。
adb shell dumpsys meminfo [パッケージ名]
galaxytabやgalaxyでやると以下のような感じで24MBを越えて確保しているのが分かります。
native dalvik other total
size: 34524 4103 N/A 38627
allocated: 34504 2949 N/A 37453
free: 19 1154 N/A 1173
(Pss): 803 1324 34084 36211
(shared dirty): 1400 4188 4276 9864
(priv dirty): 752 1156 31900 33808
ところがDesireでやってみると以下のような形でlimit 24MBという表記とともに
bitmapがどれくらいとってんよといった表示が現れ、この後に10MBのBitmapを作ったら落ちてしまいました。
native dalvik other total limit bitmap nativeBmp
size: 15912 3079 N/A 18991 24576 N/A N/A
allocated: 15845 2523 N/A 18368 N/A 12064 0
free: 18 556 N/A 574 N/A N/A N/A
(Pss): 826 927 13546 15299 N/A N/A N/A
(shared dirty): 1588 4192 1292 7072 N/A N/A N/A
(priv dirty): 760 732 12800 14292 N/A N/A N/A
ということで結論としては
foroyo以前に出た端末は何かが違うらしくてネィティブヒープは24MBくらいまでしか確保できないから、馬鹿でかいBitmapをガンガン使ったら落ちるよってことみたいです。
何が違うかは組込み業界やLinux業界の偉い人たちがそのうちブログとかに書くと思います。
最近はPHPしかやっていなかった自分にはそこまでは分からなったよw
また何か分かったらエントリーを書こうと思います。
それではノシ
以前、Androidで大きいサイズのビットマップを扱う際にBitmap.recycle()を呼び出さないとだめだとエントリー記述しました。
あれから数ヶ月がたち再びビットマップで問題が発生し、もう少し詳しい知識が付いたので再び取り扱います。
まず、Androidでは扱うヒープにいくつか種類がありDalvikヒープとネィティブヒープがあるらしいという点が重要になります。
Bitmapで画像を取り扱う場合、BitmapクラスのオブジェクトはDalvikヒープにメモリを確保しますが、Bitmapデーターの本体はネィティブヒープに領域を確保しこちらはDalvikVMの管理外となります。
そのため何が起きるかというと
Bitmapオブジェクトにnullを詰めてGCが走ってもオブジェクトは解放されるがBitmap画像そのもののデーターはネィティブヒープを確保したまま残ってしまうという事のようです。
そして今回はまったのはgalaxyやgalaxy tabでは読み込めるサイズのBitmapなのに2.1から2.2にアップデートしたDesireではOut of memoryが発生するという現象が起きました。
コチラも調べたところ、どうもforoyo以前にリリースされた端末ではアプリ毎にネィティブヒープを割り当てる制限があるらしいということ。
24MBとも16MBとも言われていましたが。。。よく分からない・・・
という事でためしにいつ落ちるかやってみた!!
adbで以下のコマンドを実行するとメモリの状況が把握できます。
adb shell dumpsys meminfo [パッケージ名]
galaxytabやgalaxyでやると以下のような感じで24MBを越えて確保しているのが分かります。
native dalvik other total
size: 34524 4103 N/A 38627
allocated: 34504 2949 N/A 37453
free: 19 1154 N/A 1173
(Pss): 803 1324 34084 36211
(shared dirty): 1400 4188 4276 9864
(priv dirty): 752 1156 31900 33808
ところがDesireでやってみると以下のような形でlimit 24MBという表記とともに
bitmapがどれくらいとってんよといった表示が現れ、この後に10MBのBitmapを作ったら落ちてしまいました。
native dalvik other total limit bitmap nativeBmp
size: 15912 3079 N/A 18991 24576 N/A N/A
allocated: 15845 2523 N/A 18368 N/A 12064 0
free: 18 556 N/A 574 N/A N/A N/A
(Pss): 826 927 13546 15299 N/A N/A N/A
(shared dirty): 1588 4192 1292 7072 N/A N/A N/A
(priv dirty): 760 732 12800 14292 N/A N/A N/A
ということで結論としては
foroyo以前に出た端末は何かが違うらしくてネィティブヒープは24MBくらいまでしか確保できないから、馬鹿でかいBitmapをガンガン使ったら落ちるよってことみたいです。
何が違うかは組込み業界やLinux業界の偉い人たちがそのうちブログとかに書くと思います。
最近はPHPしかやっていなかった自分にはそこまでは分からなったよw
また何か分かったらエントリーを書こうと思います。
それではノシ