Nativeのメモリ解放について

2,604 views
Skip to first unread message

HaL

unread,
Jul 10, 2011, 10:02:39 PM7/10/11
to 日本Androidの会
いつもお世話になっております。
HaLです。

Native部分のメモリ解放について不明な点があるので
質問させていただきます。

Native側でグローバル変数の実体を定義してdelete処理を書いていない場合、
Javaアプリケーションをfinish()メソッドを呼んで終了した時に
上記グローバル変数の実体が確保していたメモリは解放されるのでしょうか?

詳しい方いらっしゃいましたらご教示お願い致します。

Reiki Hattori

unread,
Jul 10, 2011, 10:11:19 PM7/10/11
to android-g...@googlegroups.com
服部です。

NDKで記述してもDalvik VM上で動作しています。
なので、Nativeのグローバル変数といってもJavaアプリのスレッド内に作られているはずです。


2011年7月11日11:02 HaL <hal_a...@haleng.co.jp>:

> --
> このメールは Google グループのグループ「日本Androidの会」の登録者に送られています。
> このグループに投稿するには、android-g...@googlegroups.com にメールを送信してください。
> このグループから退会するには、android-group-j...@googlegroups.com にメールを送信してください。
> 詳細については、http://groups.google.com/group/android-group-japan?hl=ja からこのグループにアクセスしてください。
>
>

HaL

unread,
Jul 10, 2011, 10:47:29 PM7/10/11
to 日本Androidの会
HaLです。
お返事ありがとうございます。

> NDKで記述してもDalvik VM上で動作しています。
> なので、Nativeのグローバル変数といってもJavaアプリのスレッド内に作られているはずです。

Nativeでグローバル変数を作ろうがローカル変数を作ろうがDalvik VM上で動くのには変わりなくて、
Javaのアプリが終了してしまえばガベージコレクションでJavaもC++も関係なくメモリの解放が行われる
という認識でよろしいのでしょうか?

On 7月11日, 午前11:11, Reiki Hattori <ley.ha...@gmail.com> wrote:
> 服部です。
>
> NDKで記述してもDalvik VM上で動作しています。
> なので、Nativeのグローバル変数といってもJavaアプリのスレッド内に作られているはずです。
>
> 2011年7月11日11:02 HaL <hal_andr...@haleng.co.jp>:

たろサ

unread,
Jul 10, 2011, 11:23:45 PM7/10/11
to android-g...@googlegroups.com
 たろサです。

> Nativeでグローバル変数を作ろうがローカル変数を作ろうがDalvik VM上で動くのには変わりなくて、
> Javaのアプリが終了してしまえばガベージコレクションでJavaもC++も関係なくメモリの解放が行われる
> という認識でよろしいのでしょうか?

 グローバル変数はリンクが切れるとgcが開放してくれると思います。
 ローカル変数はC++が開放すると思います。
 ただし、C++内でheapからmallocしたものはC++でfreeしてやらないと、Javaは知らないので開放してくれないと思います。

 C++から確保するheapはDalvikがgcで管理しているheapでは無くて、bionicのdlmallocが外から確保します。ただ、dlmallocがどこからheapを確保しているのか調べようと思ったのですが、ソースでdlmalloc.c内で

#define dlmalloc malloc

としていて、mallocを追うと手元のbionicのソースだけだと追えなかったので、よく分からないです。

 詳しい方、よろしくお願いします。

--
山本三七男 (Minao Yamamoto) ---------------- ハンドル:たろサ -----
E-Mail: taro...@gmail.com

HaL

unread,
Jul 11, 2011, 12:44:54 AM7/11/11
to 日本Androidの会
HaLです。
ローカルとグローバルで管理する部分が違うんですか。
ではグローバルで自作のクラスオブジェクトの実体を作った場合と
ローカルで同様の実体を作った場合では解放の処理が違うということでしょうか
(前者はGCで処理されて、後者はC++でfreeしないといけない)

> E-Mail: taros...@gmail.com

Reiki Hattori

unread,
Jul 11, 2011, 12:50:33 AM7/11/11
to android-g...@googlegroups.com
服部です。

あくまでも、私の体験上のお話です。
自作C++クラスでバグでアブノーマルエンドを発生した際、Dalvik VMスレッドが落ちました。

それと、C++クラスを作成する際、Freeを考慮しないで作成しGCに任せるのは、そもそも設計上間違い
でしょう。GC内で動作するから開放しなくて良いという発想の方は、Javaでプログラミングしましょう。


2011年7月11日13:44 HaL <hal_a...@haleng.co.jp>:

たろサ

unread,
Jul 11, 2011, 1:24:40 AM7/11/11
to android-g...@googlegroups.com
 たろサです。

> ローカルとグローバルで管理する部分が違うんですか。
> ではグローバルで自作のクラスオブジェクトの実体を作った場合と
> ローカルで同様の実体を作った場合では解放の処理が違うということでしょうか
> (前者はGCで処理されて、後者はC++でfreeしないといけない)

 MarkSweep.c の dvmHeapMarkRootSet()に、

LOG_SCAN("JNI global refs\n");
dvmGcMarkJniGlobalRefs();

 があってマーキングを見に行っているので、GCやってくれると思います。C++ローカルで作ったものは
C++内できちんと処理しないといけないと思います。

 服部さんのおっしゃるとおりだと思います。

E-Mail: taro...@gmail.com

HaL

unread,
Jul 11, 2011, 6:55:05 AM7/11/11
to 日本Androidの会
HaLです。

>それと、C++クラスを作成する際、Freeを考慮しないで作成しGCに任せるのは、そもそも設計上間違い
>でしょう。GC内で動作するから開放しなくて良いという発想の方は、Javaでプログラミングしましょう。

ご忠告ありがとうございます。

>マーキングを見に行っているので、GCやってくれると思います。C++ローカルで作ったものは
>C++内できちんと処理しないといけないと思います。

なるほど。
アプリを作っていて、以下の現象が起きる理由がよくわからなかったのですが、お二人のおかげでなんとかわかった気がします。
・Windowsから移植したアプリが明らかにdeleteしてない部分があったにも関わらず動いている
・cat proc/meminfoのMemFreeがアプリの動作前と動作後で変わっていない

ありがとうございました。

> E-Mail: taros...@gmail.com

HaL

unread,
Jul 12, 2011, 7:14:22 AM7/12/11
to 日本Androidの会
HaLです。
すいません、後1つ質問させていただきます。

仮に、Nativeのグローバル変数のメモリ解放をこのままGCに任せていた場合、
どのような不具合が起きると考えられるでしょうか?

Reply all
Reply to author
Forward
0 new messages