More Related Content Similar to 新版 OutOfMemoryErrorを知る (20) More from Masahiro Hidaka (11) 新版 OutOfMemoryErrorを知る7. メモリ不足に陥ったときに発生
◦ エラー発生は即死せざるを得ない。プログラマの敵。
7
05-14 17:16:45.035: INFO/ActivityManager(51): Config changed:
{ scale=1.0 imsi=310/260 loc=en_US touch=3 keys=2/1/2 nav=3/1
orien=1 layout=18}
05-14 17:16:45.075: ERROR/dalvikvm-heap(187): 2457600-byte external
allocation too large for this process.
05-14 17:16:45.075: ERROR/(187): VM won't let us allocate 2457600
bytes…省略…
05-14 17:16:45.204: ERROR/AndroidRuntime(187):
java.lang.OutOfMemoryError: bitmap size exceeds VM budget
OOMを回避するにはAndroidのメモリ管理を知るOOMを回避するにはAndroidのメモリ管理を知る
8. レジスタベースの仮想マシンレジスタベースの仮想マシン
• Dan Bornsteinおよび Google 社のエンジニアによりAndroidプラットフォームのために
設計・開発
低メモリ環境に対して最適化低メモリ環境に対して最適化
• システムプロセス Zygoteによる効率的なVMインスタンス作成
VMインスタンスの同時起動VMインスタンスの同時起動
• プロセス分離(サンドボックス)/メモリ管理/スレッドサポート
Java VM?Java VM?
• 動作するバイトコードがJavaバイトコードではない
• 独自のDex形式。厳密にはJVMではない
8
Wikipedia:dalvik
9. JavaHeap
◦ アプリ(VM)ごとに管理される
◦ VM内でスレッドを作った場合は
スレッドでも共有されるメモリ空間
◦ (※システム依存)
NativeHeap
◦ JITコンパイル展開用バッファや
◦ DalvikVMsystemの利用
Linux
◦ アプリからはアクセスできない特別な
メモリ領域。Kernel空間
2010/5/15 9日本Androidの会/日高正博
インスタンス化したObj
Java Heap
クラス
インスタンス化したObj
NativeHeap
Jitバッファ
Dalvik VM利用分
Linux
Kernel空間
メモリ管理 概念図
12. マークスイープGC(BitmapMarking手法)
◦ 3つのフェーズでメモリを管理
マーク
◦ オブジェクト使用をマーク用テーブルで管理
スイープ
◦ 未使用オブジェクトがあれば掃除する
アロケーション
◦ メモリ確保要求にあわせて空き容量を探す
12
05-14 17:43:25.916: DEBUG/dalvikvm(51):05-14 17:43:25.916: DEBUG/dalvikvm(51):
GC freed 637 objects / 29528 bytes in 86ms
13. GC実装
◦ Full GCからコンカレントGCに変更(Android 2.3)
“Stop the World”の短縮
端末性能の向上に伴い、Java Heap領域が拡張
◦ 初期heapサイズ(2MB)から
◦ Android 1.x (G1) : 16MB
◦ Android 2.x (Droid, other) : 24MB / 32MB
◦ Android 3.x (Xoom) :48MB
◦ Android 4.x (Galaxy Nexus) :64MB
◦
◦ ※あくまでJava Heapのサイズです。Native Heapについて
Dalvikは関知していない(Linuxがプロセスごとに管理)
13
14. HoneyComb(API Level 11)以降で使用可能
◦ メモリを大量に消費するアプリのために用意
Java Heapを拡張
◦ 最大256MB(Android 4.xの場合。システム依存)
14
AndroidManifest.xml
android:largeHeap="true"
ActivityManager am = (ActivityManager)getSystemService(Activity.ACTIVITY_SERVICE);
int heapSize = am.getLargeMemoryClass();
int largeHeapSize = am.getLargeMemoryClass();
Log.d("heap","Normal:" + heapSize + " Large:" + largeHeapSize);
Sample
http://developer.android.com/reference/android/app/ActivityManager.html
20. public class BitmapFactory extends Object
android.graphics.BitmapFactory
Class Overview
◦ Creates Bitmap objects from various sources, including files,
streams, and byte-arrays.
Public Methods
◦ static Bitmap decodeFile(String pathName,
BitmapFactory.Options opts) Decode a file path into a
bitmap.
◦ static Bitmap decodeResource(Resources res, int id)
Synonym for decodeResource(Resources, int,
android.graphics.BitmapFactory.Options) will null Options.
20
21. Free up the memory associated with this bitmap's
pixels, and mark the bitmap as "dead", meaning
it will throw an exception if getPixels() or
setPixels() is called, and will draw nothing.
isRecycled() Returns true if this bitmap has been
recycled.
「今は使わない」というタイミングで呼んでおくと
メモリが不足したときに自動的に解放してくれる
21
22. nativeDecodeStream
- doDecode
- decoder->decode(stream, bitmap,
prefConfig, decodeMode)
22
SkJPEGImageDecoder::onDecode
- this->allocPixelRef(bm, NULL)
- SkBitmap::allocPixels
- HeapAllocator::allocPixelRef
- sk_malloc_flags(size.get32(), 0)
sk_malloc_flags
- void* p = malloc(size);
23. javaBitmap = env->GetObjectField(options,
gOptions_bitmapFieldID);
nativeDecodeStream
- doDecode
- decoder->decode(stream, bitmap,
prefConfig, decodeMode, javaBitmap != NULL))
23
24. Bitmapの取り扱い
• Recycle/IsRecycle を活用
• BitmapFactory.Options. inPurgeable
• Bitmap.Config に ARGB_8888 からRGB_565 にするだけでメモリ使用量半分に。
画像リソース一般
• 画像など大きなリソースはDrawableをデバイスごとに用意。
大画面向けのリソース(xxhdpiなど)の縮小処理はメモリを余分に使う
• JavaHeapは使い終わったオブジェクト参照を残さない
→ setDrawableメソッドのnull代入
→ Activityコンテキストを使いまわさない(Applicationコンテキストで代用)
• System.gc()をおまじないに使う
24
25. 25
GC Bitmap LargeHeap HeapSize LruCache
1.5 Full GC Native × 16MB
1.6 Full GC Native × 16MB ○(SupportLib)
2.x Full GC Native × 24,32MB ○(SupportLib)
2.3 Concurrent GC Native × 48MB ○(SupportLib)
3.X Concurrent GC Java Heap ○(256MB) 48MB ○
4.x Concurrent GC Java Heap ○(256MB) 64MB ○
5.x
26. ご清聴ありがとうございました
◦ 他にも書きたかったこと
メモリリークの考え方
エラーは取りましょう、とかく(捕まえてエラーを修正するための情報
とする)
Activityライフサイクル
メモリリークのおきやすい箇所
ライフサイクル、コンフィグの注意する箇所
onLowMemoryが追加
WeakRefの弱体化とLruCacheの使用推奨
キャッシュの考え方
26