【发布时间】:2017-05-02 09:34:47
【问题描述】:
在加载位图时,我需要弄清楚在没有OutOfMemoryError 的情况下可以分配多少内存。我决定从文件中加载一个真正大的图像。这是它的网址:https://upload.wikimedia.org/wikipedia/commons/3/3d/LARGE_elevation.jpg
图像大小为 14 488 498 字节(磁盘上为 14.5 MB)。这是我的代码:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private static final String LOG_TAG = "LargeBitmapLargeBitmap";
private ActivityManager mActivityManager;
private ImageView mImageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mActivityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
mImageView = (ImageView) findViewById(R.id.image);
findViewById(R.id.get_mem_info).setOnClickListener(this);
findViewById(R.id.load_bitmap).setOnClickListener(this);
}
@Override
public void onClick(final View v) {
switch (v.getId()) {
case R.id.get_mem_info:
Runtime rt = Runtime.getRuntime();
Log.v(LOG_TAG, "maxMemory: " + rt.maxMemory());
Log.v(LOG_TAG, "freeMemory: " + rt.freeMemory());
Log.v(LOG_TAG, "totalMemory: " + rt.totalMemory());
Log.v(LOG_TAG, "mActivityManager.getMemoryClass(): " + mActivityManager.getMemoryClass());
break;
case R.id.load_bitmap:
new ImageLoadingTask(mImageView).execute();
break;
}
}
// I don't handle the screen rotation here since it's a test app
private static class ImageLoadingTask extends AsyncTask<Void, Void, Bitmap> {
private ImageView mImageView;
ImageLoadingTask(ImageView imageView) {
mImageView = imageView;
}
@Override
protected Bitmap doInBackground(final Void... params) {
String path = Environment.getExternalStorageDirectory().getAbsolutePath()
+ File.separator
+ "LARGE_elevation.jpg";
Bitmap bitmap = null;
try {
bitmap = BitmapFactory.decodeFile(path);
} catch (OutOfMemoryError error) {
Log.e(LOG_TAG, "Failed to load the large bitmap", error);
}
return bitmap;
}
@Override
protected void onPostExecute(final Bitmap bitmap) {
super.onPostExecute(bitmap);
mImageView.setImageBitmap(bitmap);
}
}
}
我编译了上面的代码并在我的 Nexus 5 上运行它。然后我按下get_mem_info 按钮并得到以下输出:
05-02 12:07:35.872 28053-28053/com.sample V/LargeBitmapLargeBitmap: maxMemory: 201326592
05-02 12:07:35.872 28053-28053/com.sample V/LargeBitmapLargeBitmap: freeMemory: 4991056
05-02 12:07:35.872 28053-28053/com.sample V/LargeBitmapLargeBitmap: totalMemory: 20733248
05-02 12:07:35.873 28053-28053/com.sample V/LargeBitmapLargeBitmap: mActivityManager.getMemoryClass(): 192
这意味着我的应用程序可用的堆内存为 192 MB。但是当我按下load_bitmap按钮时,图像没有加载,我得到一个OutOfMemoryError:
05-02 12:07:38.712 28053-29533/com.sample E/LargeBitmapLargeBitmap: Failed to load the large bitmap
java.lang.OutOfMemoryError: Failed to allocate a 233280012 byte allocation with 10567360 free bytes and 176MB until OOM
at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
at android.graphics.BitmapFactory.decodeStreamInternal(BitmapFactory.java:635)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:611)
at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:391)
at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:417)
at com.sample.MainActivity$ImageLoadingTask.doInBackground(MainActivity.java:70)
at com.sample.MainActivity$ImageLoadingTask.doInBackground(MainActivity.java:55)
为什么会这样?为什么系统需要分配 233280012 字节(约 220MB)? “10567360 个可用字节和 176MB 直到 OOM”这部分对我来说也很奇怪。为什么我会看到这些数字?
【问题讨论】:
-
@MuhammadBabar,是的。但实际上我的问题是关于那些奇怪的数字
标签: android bitmap out-of-memory