自分も、調査中です。
調査のため、ツールを作ってます。
Another availMem
タスクキラーです。
Another System Info
メモリーの領域毎使用を表示します。ついでにopenglも
調査方法は、アプリの起動前後のメモリの使用量を
確認します。
アプリは、タスクキラーで消さないとメモリに残ります。
アプリ起動にメモリ足りないと、バックのアプリが
消されます。(この辺りは、タスクキラーで見れる)
nativeからは、7mbは使えました。
たぶん10mb辺りが限界かと。
すいません上記、有料です。
> --
> このメールは Google グループのグループ「日本Androidの会」の登録者に送られ
て
> います。
> このグループに投稿するには、android-g...@googlegroups.com にメール
を
> 送信してください。
> このグループから退会するには、
> android-group-j...@googlegroups.com にメールを送信してくださ
い
> 。
> 詳細については、http://groups.google.com/group/android-group-japan?hl=ja
か
> らこのグループにアクセスしてください。
>
>
>
私の理解なので、間違っていたら、どなたか訂正お願いします。
NativeコードもDalvikVMが確保するメモリも同じheap(bionic libc管理)から
確保していると理解しています。
ただし、DalvikVMから確保できるheapの量は規定されていると理解していま
す。なので、DalvikVMの規定heap量を超えてなくても、bionic libcにメモリを
もらいに行ったときに、heapが足りないと、エラーになって確保できませんし、
heapに余裕があっても、アプリの規定heap量を超えてメモリを確保しようとして
も、エラーになって確保できない。と理解しています。
DalvikVMの方は、中でメモリリークしないように作っているとは思いますが、
Nativeコードはちゃんと開放しないとメモリリークすると思います。
--
山本三七男 (Minao Yamamoto) ---------------- ハンドル:たろサ -----
E-Mail: taro...@gmail.com
便乗質問なのですが、mallocとfreeのinternal callは、dlmallocにdefineさ
れていると思っていたのですが、
bionic/libc/bionic/dlmalloc.cのinternal callのdefineの部分を、
下記のように書き換えてみたところ、internal_mallocとinternal_freeがdefine
していないとエラーで怒られました。
---
#if ONLY_MSPACES
//#define internal_malloc(m, b) mspace_malloc(m, b)
//#define internal_free(m, mem) mspace_free(m,mem);
#else /* ONLY_MSPACES */
#if MSPACES
//#define internal_malloc(m, b) (m == gm)? dlmalloc(b) :
mspace_malloc(m, b)
//#define internal_free(m, mem) if (m == gm) dlfree(mem); else
mspace_free(m,mem);
#else /* MSPACES */
#define internal_malloc(m, b) dlmalloc(b)
#define internal_free(m, mem) dlfree(mem)
#endif /* MSPACES */
#endif /* ONLY_MSPACES */
---
あれ?と思って、下記のように変更してmakeしても、internal_mallocと
internal_freeがdefineしていないとエラーで怒られました。
---
#if ONLY_MSPACES
#define internal_malloc(m, b) mspace_malloc(m, b)
#define internal_free(m, mem) mspace_free(m,mem);
#else /* ONLY_MSPACES */
#if MSPACES
//#define internal_malloc(m, b) (m == gm)? dlmalloc(b) :
mspace_malloc(m, b)
//#define internal_free(m, mem) if (m == gm) dlfree(mem); else
mspace_free(m,mem);
#else /* MSPACES */
//#define internal_malloc(m, b) dlmalloc(b)
//#define internal_free(m, mem) dlfree(mem)
#endif /* MSPACES */
#endif /* ONLY_MSPACES */
---
おやおや?と思って、下記のように変更してmakeすると、通りました。
---
#if ONLY_MSPACES
#define internal_malloc(m, b) mspace_malloc(m, b)
#define internal_free(m, mem) mspace_free(m,mem);
#else /* ONLY_MSPACES */
#if MSPACES
//#define internal_malloc(m, b) (m == gm)? dlmalloc(b) :
mspace_malloc(m, b)
//#define internal_free(m, mem) if (m == gm) dlfree(mem); else
mspace_free(m,mem);
#else /* MSPACES */
#define internal_malloc(m, b) dlmalloc(b)
#define internal_free(m, mem) dlfree(mem)
#endif /* MSPACES */
#endif /* ONLY_MSPACES */
---
原因がいまいちよく分からないのですが、internal_mallocは、dlmallocを
使っているのでしょうか、それとも、mspace_mallocを使っているのでしょうか。
もしかしたら、dalvikVMのmakeの際にはmspace_mallocを使って、libcのmake
にdlmallocを使っているなんて、そんなことは無いですよね。
どなたか、教えてください。makeしたソースは2.2.2_r1です。
よろしくお願いします。
自己解決です。
結論から言うと、HeapSource.cでは、internal callは、mspace_が呼ばれて、
それ以外は、dlmalloc, dlfreeが呼ばれるということでした。
ソースを追っかけてみると、mspace.hに、下記のように定義されていました。
---
#define MSPACES 1
#define ONLY_MSPACES 1
#include "../../../../bionic/libc/bionic/dlmalloc.h"
---
mspace.hは、HeapSource.cでincludeされているので、HeapSource.cをコンパ
イルするときは、dlmalloc.hで、下記のところで、internal_mallocは、
mspace_mallocと定義されてコンパイルされるようです。
---
#if ONLY_MSPACES
#define internal_malloc(m, b) mspace_malloc(m, b)
#define internal_free(m, mem) mspace_free(m,mem);
#else /* ONLY_MSPACES */
...
---
mspace.hをincludeしていない場合は、dlmalloc.c中の下記のところで、
ONLY_MSPACESもMSPACESも、0になるようです。
---
#ifndef ONLY_MSPACES
#define ONLY_MSPACES 0
#endif /* ONLY_MSPACES */
#ifndef MSPACES
#if ONLY_MSPACES
#define MSPACES 1
#else /* ONLY_MSPACES */
#define MSPACES 0
#endif /* ONLY_MSPACES */
#endif /* MSPACES */
---
それで、その後にある#ifのところで、
---
#define internal_malloc(m, b) dlmalloc(b)
#define internal_free(m, mem) dlfree(mem)
---
が定義されることになります。
2.2.2_r1だと、ONLY_MSPACESが0で、MSPACESが1という#defineが無いので、下
記の定義は通らないようです。
---
#define internal_malloc(m, b)\
(m == gm)? dlmalloc(b) : mspace_malloc(m, b)
#define internal_free(m, mem)\
if (m == gm) dlfree(mem); else mspace_free(m,mem);
---
すいません、お騒がせしました。Android難しいよー。
すっかり、時間が経ってしまいましたが、ソースを追いかけて、やっと、メモリの使われ方について理解しました(したつもりです)。ソースは2.2.2_r1です。
Nativeコードからmallocするときは、dlmalloc()が呼ばれるので、カーネルが管理するグローバルなメモリから確保されます(malloc_state _gm_を見に行く)。
DalvikVMは、Zygote()からforkされてアプリが起動するときに、最大heap領域をmmap()によって確保し、アプリは、以後、mmap()からメモリを確保します。forkされるたびにmmap()が確保されるので、アプリ毎に別々のheap領域(mmap())を持つことになります。ただし、Zygote()の基本モジュールはmmap()内で同じ物理アドレスにマッピングされています。
また、同時にもう1つ別にmmap()が確保されており、これはメモリを割り当てた箇所を別に管理するobjectBitmapという管理テーブル用に確保されています。
ここで、1つわかったことが、javaの中のライブラリで、JNIからNativeのプログラムが呼ばれている場合、Javaコードといえども、Nativeで作られているため、dlmalloc()でカーネルから直接メモリを確保しているということです。
ここら辺を抑えておけば、メモリ管理を理解するのが早いのかもしれません。
linuxの知識が無かったので、理解するのにすごく時間が掛かってしまいました。
1つ不思議なのは、mspace.cのmspace create_contiguous_mspace_with_name()で、
---
fd = ashmem_create_region(buf, max_capacity);
base = mmap(NULL, max_capacity, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
close(fd);
---
のように、mmap()を確保したとたんに、close(fd)しているところです。これはこういうものなのでしょうか???
次は、2.3.3に挑戦かな。DalvikVM内のthread処理がどう変っているのかという興味ですね。
ちなみに、少し読んだのですが、2.3.3はHeapSourceからHeapは2こしか取られなくなっています(Heap heaps[2]ですね)。それで、Heap構造体内にHeapBitmapを持っている必要が無くなったらしく、HeapSourceの方に出してきて、mmap()でliveBitsとmarkBitsと2つのHeapBitmapを確保していますね。こっちの方がスッキリしますね。
どうも、お騒がせしました。どなたか、上の疑問が分かれば、教えてください。
よろしくお願いします。
(2011/03/31 0:20), peach wrote:
--
山本三七男 (Minao Yamamoto) ---------------- ハンドル:たろサ -----
Androidで簡単にプログラミングできるLuarida無料公開中。よろしくね!
http://d.hatena.ne.jp/tarosay/
たろサです。
> ファイルディスクリプタをcloseしても、仮想アドレス空間にマップされた領域は
> munmapされるまで有効です。
manで確認しました。しっかり書いていました。
ありがとうございます。
(2011/06/13 8:42), yoshiyuki kanno wrote:
> 菅野です。
>
> ファイルディスクリプタをcloseしても、仮想アドレス空間にマップされた領域は
> munmapされるまで有効です。
> なので不要なリソースは即削除しているのでしょう。
> 詳細はmmapのmapページを参照してみてください。
>
> 2011年6月13日2:21 tarosa <taro...@gmail.com <mailto:taro...@gmail.com>>:
> <mailto:android-g...@googlegroups.com> にメールを送信してくだ
> さい。
> このグループから退会するには、android-group-
> japan+un...@googlegroups.com
> <mailto:android-group-japan%2Bunsu...@googlegroups.com> にメール
> を送信してください。
> 詳細については、http://groups.google.com/group/android-group-
> japan?hl=ja からこのグループにアクセスしてください。
>
>
> --
> このメールは Google グループのグループ「日本Androidの会」の登録者に送ら
> れています。
> このグループに投稿するには、android-g...@googlegroups.com にメー
> ルを送信してください。
> このグループから退会するには、android-group-
> japan+un...@googlegroups.com にメールを送信してください。
> 詳細については、http://groups.google.com/group/android-group-japan?hl=ja
> からこのグループにアクセスしてください。
--