2011/02/23

Android NDK側のメモリーリークを調べる

Androidのカメラプレビューを使って色々と実験しているのですが、
1分ぐらい動かしていたらアプリが勝手に落ちてしまいます。

不思議に思い、DDMSを使ってメモリの使用量を監視してみましたが、
使用率が70%位を維持しつつ、いきなりアプリが落ちる現象が繰り返し発生しました。
ログメッセージには、

   CameraServer   binderDie() start Client died


といった感じのメッセージが表示されていました。

なんだろコレ。。。
ググってもあまり情報が出てきません。

ネイティブ側にgetPixelsで取得したプレビューデータを渡しているところを
コメントアウトしたところ、現象は起こりませんでした。

となると、ネイティブ側に何か問題があるようです。

メモリー使用率やCPU使用率を見張るために、下記のコマンドを実行しました。

  adb shell
  top -m 10

AndroidはLinuxをベースにしており、adb shellを使うとLinuxコマンドを一部使えるようになります。
topというコマンドを実行すると、定期的にプロセスごとのCPU使用率やメモリ使用量を画面に表示してくれます。


topコマンドの出力例:
User 87%, System 7%, IOW 0%, IRQ 0%
User 293 + Nice 0 + Sys 25 + Idle 17 + IOW 0 + IRQ 0 + SIRQ 0 = 335


  PID CPU% S  #THR     VSS     RSS PCY UID      Name
   31  47% S     6  24708K   6296K  fg media    /system/bin/mediaserver
  210  43% R     6 106636K  24272K  fg app_29   com.camera.preview
  234   2% R     1    892K    384K  fg root     top
   52   2% S    41 148860K  30340K  fg system   system_server
    5   0% S     1      0K      0K  fg root     khelper
    6   0% S     1      0K      0K  fg root     suspend
    7   0% S     1      0K      0K  fg root     kblockd/0
    8   0% S     1      0K      0K  fg root     cqueue
    9   0% S     1      0K      0K  fg root     kseriod
   10   0% S     1      0K      0K  fg root     kmmcd

修正前のプログラムでは、com.camera.previewのVSSという数字がだんだんと大きくなっていき、
それにつれて他のプロセスが消され、最後にcom.camera.previewが消されてしまいました。

これぞ”メモリーリーク”と呼ばれ、忌み嫌われているアレです。
まぁ、リークさせてるのは私のコードなのですが。。。

コードを調べたところ、今回はOpenCVの画像形式であるIplImageの開放漏れがメモリーリークを引き起こしていました。

NDKを使ったアプリを作成する場合は、topコマンドを使用して常にメモリ使用量を見張るようにした方が良さそうです。

ではまた。

0 件のコメント:

コメントを投稿