2016016字节分配时内存不足。错误?

时间:2014-02-21 12:06:35

标签: java android out-of-memory json

我正在下载波形(图像)并解码它们。它们的尺寸非常大。所以我的主要问题是,当我安装应用程序时,它工作得很好。但是经过一段时间后,Logcat突然发出以下错误。我想我保存了太多波形。所以现在我需要删除保存的波形。那么如何删除保存的波形呢?

02-21 17:06:30.146: I/dalvikvm-heap(13642): Clamp target GC heap from 259.610MB to    256.000MB
02-21 17:06:30.146: D/dalvikvm(13642): GC_FOR_ALLOC freed 453K, 2% free    257622K/262108K, paused 113ms, total 113ms
02-21 17:06:30.154: I/dalvikvm-heap(13642): Forcing collection of SoftReferences for 2016016-byte allocation
02-21 17:06:30.232: I/dalvikvm-heap(13642): Clamp target GC heap from 259.609MB to 256.000MB
02-21 17:06:30.232: D/dalvikvm(13642): GC_BEFORE_OOM freed 1K, 2% free 257620K/262108K, paused 85ms, total 85ms
02-21 17:06:30.240: E/dalvikvm-heap(13642): Out of memory on a 2016016-byte allocation.
02-21 17:06:30.240: I/dalvikvm(13642): "AsyncTask #5" prio=5 tid=18 RUNNABLE
02-21 17:06:30.240: I/dalvikvm(13642):   | group="main" sCount=0 dsCount=0 obj=0x41e3a290 self=0x40067e08
02-21 17:06:30.240: I/dalvikvm(13642):   | sysTid=13699 nice=10 sched=0/0 cgrp=apps/bg_non_interactive handle=1492300400
02-21 17:06:30.240: I/dalvikvm(13642):   | state=R schedstat=( 0 0 0 ) utm=3297 stm=228 core=1
02-21 17:06:30.240: I/dalvikvm(13642):   at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
02-21 17:06:30.240: I/dalvikvm(13642):   at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:529)
02-21 17:06:30.240: I/dalvikvm(13642):   at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:601)
02-21 17:06:30.240: I/dalvikvm(13642):   at com.blackcobrastudios.footballchants.manager.SoundCloudManager.readBitmapFromResponse(SoundCloudManager.java:493)
02-21 17:06:30.240: I/dalvikvm(13642):   at com.blackcobrastudios.footballchants.manager.SoundCloudManager$TaskCaller.doInBackground(SoundCloudManager.java:323)
02-21 17:06:30.240: I/dalvikvm(13642):   at com.blackcobrastudios.footballchants.manager.SoundCloudManager$TaskCaller.doInBackground(SoundCloudManager.java:1)
02-21 17:06:30.240: I/dalvikvm(13642):   at android.os.AsyncTask$2.call(AsyncTask.java:287)
02-21 17:06:30.240: I/dalvikvm(13642):   at java.util.concurrent.FutureTask.run(FutureTask.java:234)
02-21 17:06:30.240: I/dalvikvm(13642):   at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
02-21 17:06:30.240: I/dalvikvm(13642):   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
02-21 17:06:30.240: I/dalvikvm(13642):   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
02-21 17:06:30.240: I/dalvikvm(13642):   at java.lang.Thread.run(Thread.java:856)
02-21 17:06:30.240: D/skia(13642): --- decoder->decode returned false

我不明白发生了什么,当我收到这些错误时,我的波形没有下载。

public Bitmap readBitmapFromResponse(HttpResponse response)
        throws IOException, OutOfMemoryError {
    HttpEntity entity = response.getEntity();
    BufferedHttpEntity b_entity = new BufferedHttpEntity(entity);
    InputStream inputStream = b_entity.getContent();

    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeStream(inputStream, null, options);

    options.inSampleSize = calculateInSampleSize(options, 1024, 16);

    Log.d("WAVE_SIZE", "Sample size = " + options.inSampleSize);

    options.inJustDecodeBounds = false;
    inputStream.reset();

    return BitmapFactory.decodeStream(inputStream);
}

public static int calculateInSampleSize(
        BitmapFactory.Options options, int reqWidth, int reqHeight) {
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) {

        final int halfHeight = height / 2;
        final int halfWidth = width / 2;
        while ((halfHeight / inSampleSize) > reqHeight
                && (halfWidth / inSampleSize) > reqWidth) {
            inSampleSize *= 2;
        }
    }

    return inSampleSize;
}

2 个答案:

答案 0 :(得分:8)

如果您的最低版本的sdk为11或更高,请尝试此操作

将以下内容添加到清单

中的应用标记中
android:largeHeap="true"

有些人说这不是最好的方式,但在我的应用程序中它完美运行所以我建议你。

希望它会对你有所帮助。

答案 1 :(得分:1)

经过一番研究后,我遇到了问题。实际上波形(数据)即将到来,但是当我点击后退按钮时,它没有清除数据。所以我使用了bitmap.recycle()。 但它正在崩溃我的应用程序。所以我把它放在一个线程中。 这是我的代码。

 @Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        Intent i = new Intent(this, MainActivity.class);
        i.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
        this.startActivity(i);
        MusicManager.getInstance().stopIfPlaying();
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {

                for (final TrackData track : SoundCloudManager
                        .getInstance().mTrackData) {
                    try {
                        if (track.getBitmap() != null
                                && !track.getBitmap().isRecycled()) {
                            track.getBitmap().recycle();
                            track.setBitmap(null);
                            // finish();
                        }
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }

                }
                SoundCloudManager.getInstance().mTrackData.clear();
                SoundCloudManager.getInstance().mTrackData = new ArrayList<TrackData>();
            }
        }, 1000);
        System.gc();
        Runtime.getRuntime().gc();
        SoundCloudManager.getInstance().clearTask();
        return true;
    }

    return super.onKeyDown(keyCode, event);
}