У меня проблема при попытке мониторинга системной памяти, пытающейся угадать, помещается ли растровое изображение в память перед загрузкой.
Вот мой код:
public class MemoryCrashTestActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
String url="http://wallpapers-database.com/images/12_wallpaper_xbiz.jpg";
ArrayList<Bitmap> images= new ArrayList<Bitmap>();
while(true){
checkBitmapFitsInMemory(1600,1200,4);
images.add(getImageBitmapFromUrl(url));
}
}
public static boolean checkBitmapFitsInMemory(long bmpwidth,long bmpheight, int bmpdensity ){
long reqsize=bmpwidth*bmpheight*bmpdensity;
long allocNativeHeap = Debug.getNativeHeapAllocatedSize();
Log.w("test","Allocated mem="+allocNativeHeap/1024+" of total="+Runtime.getRuntime().maxMemory()/1024+" required= "+reqsize/1024);
if ((reqsize + allocNativeHeap+3*1024*1024) >= Runtime.getRuntime().maxMemory())
{
Log.e("test","Next load will crash due to low memory");
return false;
}
return true;
}
public static Bitmap getImageBitmapFromUrl(String url){
URL aURL;
Bitmap result = null;
try {
aURL = new URL(url);
URLConnection conn = aURL.openConnection();
conn.connect();
InputStream is = conn.getInputStream();
result= BitmapFactory.decodeStream(is);
is.close();
} catch (Exception e) {
e.printStackTrace();
return null;
}
return result;
}
}
Если я запустил его на Samsung Galaxy S1 (под управлением Android 2.3.4), то получится:
Allocated mem=7911 of total=65536 required= 7500
Allocated mem=11663 of total=65536 required= 7500
Allocated mem=15474 of total=65536 required= 7500
Allocated mem=19234 of total=65536 required= 7500
Allocated mem=22986 of total=65536 required= 7500
Allocated mem=26738 of total=65536 required= 7500
Allocated mem=30490 of total=65536 required= 7500
Allocated mem=34242 of total=65536 required= 7500
Allocated mem=37994 of total=65536 required= 7500
Allocated mem=41747 of total=65536 required= 7500
Allocated mem=45499 of total=65536 required= 7500
Allocated mem=49251 of total=65536 required= 7500
Allocated mem=53003 of total=65536 required= 7500
Allocated mem=56755 of total=65536 required= 7500
Allocated mem=60507 of total=65536 required= 7500
Next load probably will crash due to low memory
FATAL EXCEPTION: main
java.lang.OutOfMemoryError: bitmap size exceeds VM budget
at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:573)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:628)
at com.example.memorycrash.MemoryCrashTestActivity.getImageBitmapFromUrl(MemoryCrashTestActivity.java:56)
at com.example.memorycrash.MemoryCrashTestActivity.onCreate(MemoryCrashTestActivity.java:26)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1615)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1667)
at android.app.ActivityThread.access$1500(ActivityThread.java:117)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3687)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:842)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
at dalvik.system.NativeStart.main(Native Method)
Кажется, работает. Аналогичный вывод, если я использую HTC Wildfire. Но при попытке с преобразователем Asus Eee Pad (Android 3.1) это вывод:
Allocated mem=2585 of total=49152 required= 7500
Allocated mem=2588 of total=49152 required= 7500
Allocated mem=2647 of total=49152 required= 7500
Allocated mem=2655 of total=49152 required= 7500
Allocated mem=2656 of total=49152 required= 7500
Allocated mem=2656 of total=49152 required= 7500
Allocated mem=2656 of total=49152 required= 7500
Allocated mem=2656 of total=49152 required= 7500
Allocated mem=2656 of total=49152 required= 7500
Allocated mem=2656 of total=49152 required= 7500
Allocated mem=2657 of total=49152 required= 7500
Allocated mem=2657 of total=49152 required= 7500
ERROR/dalvikvm-heap(1398): Out of memory on a 3840016-byte allocation.
08-06 05:05:19.490: WARN/dalvikvm(1398): threadid=1: thread exiting with uncaught exception (group=0x40168760)
FATAL EXCEPTION: main
java.lang.OutOfMemoryError
at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:493)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:549)
at com.example.memorycrash.MemoryCrashTestActivity.getImageBitmapFromUrl(MemoryCrashTestActivity.java:56)
at com.example.memorycrash.MemoryCrashTestActivity.onCreate(MemoryCrashTestActivity.java:26)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1048)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1712)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1764)
at android.app.ActivityThread.access$1500(ActivityThread.java:122)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1002)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:132)
at android.app.ActivityThread.main(ActivityThread.java:4025)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:491)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
at dalvik.system.NativeStart.main(Native Method)
Почему это происходит?
Спасибо