android アプリを開発するにあたって、扱われる Java のヒープは
Dalvik ヒープ と ネイティブヒープ がありますが、製作している
プログラムの負荷テストを行いたいため、これらのメモリを圧迫する
手軽な方法をご存じの方がいらっしゃいましたらお教えいただけ
ませんでしょうか。
Dalvik ヒープはアプリケーション内で
buff = ByteBuffer.allocateDirect(1024*1024*4)
などを繰り返せば圧迫できるようですが、
ネイティブヒープの圧迫が今ひとつ理解しきれていません。
2.1 以前の OS であれば、大きな Bitmap を recycle せずに使い
続ければ圧迫できるようですが、2.2 以降のOSであるため
この方法は使えないようです。
また、Dalvik ヒープはアプリケーションとしての制限である 16MB
以上のメモリを確保できないと認識しておりますが、この制限を
突破してメモリを確保する事は可能でしょうか。
理想としては、独立した一つのアプリケーションとして作成して
目的のアプリケーションに対して外部からメモリ圧迫による
ストレステストを行いたいと考えております。テスト用なので、
ワンボタンで残りメモリの9割くらいを一度に確保して、
可能ならいつでも圧迫したメモリを解放できるような仕様に
なれば理想的です。
皆様のお知恵を拝借させていただきたく。よろしくお願いします。
ヒープが枯渇すると、ヒープを確保したServiceも簡単に殺されるので
Foreground Service としてしておくと、より良いと思います。
米 forground serviceだからといって、殺されないわけではないです
16MBの突破するには、AndroidManifestに別プロセスで、
起動するように指定された Serviceいくつか作成してください
おのおののサービスに16MBヒープをかくほすれば
メモリを圧迫(16*serviceの数だけ)できます
--
このメールは Google グループのグループ「Android-SDK-Japan」の登録者に送られています。
このグループに投稿するには、android-...@googlegroups.com にメールを送信してください。
このグループから退会するには、android-sdk-ja...@googlegroups.com にメールを送信してください。
詳細については、http://groups.google.com/group/android-sdk-japan?hl=ja からこのグループにアクセスしてください。
江川と申します。
> buff = ByteBuffer.allocateDirect(1024*1024*4)
これはネイティブヒープになるかと思います。ネイティブヒープにはグローバルリファレンスの話なども絡んできて少々ややこしいので、allocateDirectでもいいんですが、JNI側でmallocするのが最も単純なんじゃないかな、と思います。Dalvik
ヒープについては、new しまくって参照を保持していれば減っていくんじゃないかな、と思います。
河村さんのおっしゃる方法は、VMのインスタンスを増やしてDalvik側のヒープを増やすことで間接的にネイティブヒープを圧迫する形になるのではないかと想像しています。面白い方法ですね。
個人的には、自分のアプリのメモリ使用推移が常識的な範囲内に収まっていることを確認できているならそれでいいんじゃないかと思ってしまい、恥ずかしながら負荷テストをやってどのような価値があるか想像できるまでに至っていないのですが、どのような観点でのテストをしたいかによると思いますので、アプリの特性に合わせて適した方法を選ぶのがよいのではないかと思います。
------------------------------------------
EGAWA Takashi
2012年2月21日17:05 Kou Sumeragi <kou...@gmail.com>:
> 河村さんのおっしゃる方法は、VMのインスタンスを増やしてDalvik側のヒープを増やすことで間接的にネイティブヒープを圧迫する形になるのではないかと想像しています。面白い方法ですね。
誤解させてしまいました。
私の説明では、ネイティブヒープについては触れてません。
Dalvikヒープについてだけ触れています。
具体的には、Kou Sumeragi さんの発言した以下の部分について触れています。
>> また、Dalvik ヒープはアプリケーションとしての制限である 16MB
>> 以上のメモリを確保できないと認識しておりますが、この制限を
>> 突破してメモリを確保する事は可能でしょうか。
>> ...
>> ...ワンボタンで残りメモリの9割くらいを一度に確保して、
>> ...
※ プロセスごとに、使用できるヒープは16MB程度 (PFによる)
Kou Sumeragi さんは、以下のような状況を作りたいのではないかと推測しています。
1. Dalvikが使用可能なヒープ全体の90%を使用して、10%としかあいていない
状態を作る。
2. 1の状態でウニョウニョとテストする。
というわけで、「Serviceごとにプロセスを割り振れば、16MB×プロセス数ぶんだけ
Dalvikのヒープを占有できますよ」ということが言いたい。
うまくすれば、Dalvik全体の90%を使用しているような状況を作れるかもしれません。
そんな感じです。
そろそろ寝ます。
[PS]
具体的にここで、Dalvikヒープとしているのは、
adb shell dumpsys meminfo <Package名>
にて、dalvikの列に表示されるヒープの事とみなして話しています。
この場合、「buff = ByteBuffer.allocateDirect(1024*1024*4)」は
dalvikヒープだったと思います。
> 具体的にここで、Dalvikヒープとしているのは、
> adb shell dumpsys meminfo <Package名>
> にて、dalvikの列に表示されるヒープの事とみなして話しています。
>
> この場合、「buff = ByteBuffer.allocateDirect(1024*1024*4)」は
> dalvikヒープだったと思います。
憶測で発言していました。
dalvikヒープだという根拠がないので、この部分は取り消します。
2012年2月22日3:30 河村潔広 <kyor...@gmail.com>:
Service 別スレッドでメモリを確保する方法、および JNI で malloc する方法など
とても参考になりました。
最終的にやりたいのは、Low Memory Killer が発生するような状態を発生させて、
開発中のアプリケーションがどのような挙動をするのかを確認したいのです。
ものすごい極論を言うと、adb などで Low Memory Killer イベントを発生させて
その挙動を確認するという方法でも構わないのですが、その方法が見つかりません
でした。同様に、Low Memory Killer を発生させるようなメモリ圧迫ツールの存在も
探してみましたが見つかりません。(あるのかもしれませんが、non rooted な借用端末
ですので rooted アプリでは無理です)
復習の意味もかねて、現時点での理解とやりたい事、作るべき物をまとめてみます。
android で扱うメモリには大きくわけて2種類があり、
1)Linux ヒープ
搭載されている物理的なRAMの全領域を扱って、android OS 全体に使われる。
OS やカーネルに割り当てられるメモリの他に、以下のアプリケーションヒープも含まれる。
2)アプリケーションヒープ
各アプリケーション毎に OS によって割り当てられるメモリ領域で、多くの機種で
デフォルトで 16MB ほど。JDK で作られたアプリケーションはこのメモリを使う。
このヒープも大きく分けて2種類に分類される。
2-A) Dalvik (Java) ヒープ
Dalvik (Java) が使う変数などを配置するメモリ。
2-B)ネイティブヒープ
Bitmap などのリソースで扱うメモリ。
メモリエラーの種類
1)のメモリが不足すると、Low Memory Killer が自動で発動し、現在実行されている
アプリが自動的に KILL される(ものがある)
この2-A)、2-B) の合計が16MBを超すると、Out Of Memory エラーが発生する。
提案された方法の解釈
・JNI で malloc する方法
JNI の中で malloc する事で直接 1)のメモリを圧迫するため、Low Memory Killer を
呼び出せる?それとも JNI で malloc をかけても圧迫されるメモリは 2-B)のメモリ
なので Out Of Memory エラーが発生する?
・別スレッド Service を16MBづつメモリ確保して複数起動する。
2)のメモリをどんどん確保する事で間接的に 1)のメモリを圧迫するため
Low Memory Killer を呼び出せる?
申し訳ありません、このへんがまだ十分に理解できておりません。また、
1つのアプリケーションヒープの領域を他のアプリケーションから圧迫する事はできるのか、
などの android のメモリ管理に関する基本的な知識が欠如している事は自覚しており
ます。「このへん読んどけ」みたいなドキュメントがありましたらポインタでもいいので
お教えいただけませんでしょうか。
長々とした返信になりましたが、よろしくお願いします。
2012年2月22日3:59 egg <t.e...@gmail.com>:
> 別スレッド Service を16MBづつメモリ確保して複数起動する。 2)のメモリをどんどん確保する事で間接的に 1)のメモリを圧迫するため Low Memory Killer を呼び出せる?
念のため、別スレットでもまちがいないですが
別プロセスである必要があります。
Low Memory Killerは発生します
米 少なくとも以前私が試した端末ではおこせたので...、断言するほど自信はありませんが...
そんな感じです
kyorohiroです
> ます。「このへん読んどけ」みたいなドキュメントがありましたらポインタでも いいので お教えいただけませんでしょうか。
レスしている文面から、Low Memory Killerにかんする
情報源には差がないようないがしました。
なので、特別これを読め的なものはないです。
時間に余裕あるならば、該当するandroidコードを読むと良いと思います。
解説できるほど詳しくも無いので、こんな感じで...
おそまつさまです。
ご教示いただいた皆様、ありがとうございました。