【问题标题】:How to reduce memory usage in Android?如何减少Android中的内存使用量?
【发布时间】:2015-07-10 15:37:57
【问题描述】:

当我按下按钮时,我想从我的可绘制文件夹中显示一些随机图像。

我将我的照片命名为“img_0”...改名为“img_51”

这是我尝试过的:

ImageView card1, card2, card3, card4, card5;
Button bPlay;

ArrayList<Integer> numbers = new ArrayList<Integer>();
Random randomGenerator = new Random();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN);

    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

    setContentView(R.layout.activity_play);

    setReferences();
}


private void setReferences() {
    card1 = (ImageView) findViewById(R.id.card1);
    card2 = (ImageView) findViewById(R.id.card2);
    card3 = (ImageView) findViewById(R.id.card3);
    card4 = (ImageView) findViewById(R.id.card4);
    card5 = (ImageView) findViewById(R.id.card5);
    bPlay = (Button) findViewById(R.id.bPlay2);
    bPlay.setOnClickListener(this);
}

private void getRandomNumbers() {
    while(numbers.size() < 5) {
        int random = randomGenerator .nextInt(51);
        if (!numbers.contains(random)) {
            numbers.add(random);
        }
    }
}

private void clearArrayList() {
    for(int i = numbers.size()-1 ; i >= 0; i--){
        numbers.remove(numbers.get(i));
    }
}

private void setBitmap(ImageView iv, int n) {
    String str = "img_" + numbers.get(n);

    int resID = getResources().getIdentifier(str, "drawable",  getPackageName());
    iv.setImageResource(resID);
}

@Override
public void onClick(View v) {
    getRandomNumbers();

    setBitmap(card1, 0);
    setBitmap(card2, 1);
    setBitmap(card3, 2);
    setBitmap(card4, 3);
    setBitmap(card5, 4);

    clearArrayList();
}

我在模拟器中查看内存选项卡,发现内存使用率非常高...

如何减少内存使用量?只有当我按下一次按钮时,它有 70 和 VM HEAP 中的一些东西。

非常欢迎任何想法!

我也尝试过使用 Bitmap 并回收,但它给了我错误。应用程序已停止工作...

这是我尝试过的:

private void setBitmap(ImageView iv, int n) {
        String str = "img_" + numbers.get(n);
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), getResourceID(str, "drawable",
                this));
        iv.setImageBitmap(bitmap);
        bitmap.recycle();
    }

这里是日志:

    07-10 16:57:10.402    1906-1906/? I/art﹕ Not late-enabling -Xcheck:jni (already on)
07-10 16:57:14.321    1906-1937/com.symplyfyweb.gherghina.oldschoolwesternpoker D/OpenGLRenderer﹕ Use EGL_SWAP_BEHAVIOR_PRESERVED: true
07-10 16:57:14.335    1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker D/﹕ HostConnection::get() New Host Connection established 0xb4a93f40, tid 1906
07-10 16:57:14.349    1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker D/Atlas﹕ Validating map...
07-10 16:57:14.813    1906-1937/com.symplyfyweb.gherghina.oldschoolwesternpoker D/﹕ HostConnection::get() New Host Connection established 0xb4b270b0, tid 1937
07-10 16:57:14.957    1906-1937/com.symplyfyweb.gherghina.oldschoolwesternpoker I/OpenGLRenderer﹕ Initialized EGL, version 1.4
07-10 16:57:15.032    1906-1937/com.symplyfyweb.gherghina.oldschoolwesternpoker D/OpenGLRenderer﹕ Enabling debug mode 0
07-10 16:57:15.054    1906-1937/com.symplyfyweb.gherghina.oldschoolwesternpoker W/EGL_emulation﹕ eglSurfaceAttrib not implemented
07-10 16:57:15.063    1906-1937/com.symplyfyweb.gherghina.oldschoolwesternpoker W/OpenGLRenderer﹕ Failed to set EGL_SWAP_BEHAVIOR on surface 0xb4b23b00, error=EGL_SUCCESS
07-10 16:57:15.169    1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker I/Choreographer﹕ Skipped 38 frames!  The application may be doing too much work on its main thread.
07-10 16:57:16.748    1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker I/Choreographer﹕ Skipped 93 frames!  The application may be doing too much work on its main thread.
07-10 16:57:22.533    1906-1937/com.symplyfyweb.gherghina.oldschoolwesternpoker W/EGL_emulation﹕ eglSurfaceAttrib not implemented
07-10 16:57:22.533    1906-1937/com.symplyfyweb.gherghina.oldschoolwesternpoker W/OpenGLRenderer﹕ Failed to set EGL_SWAP_BEHAVIOR on surface 0xb4b23cc0, error=EGL_SUCCESS
07-10 16:57:23.378    1906-1913/com.symplyfyweb.gherghina.oldschoolwesternpoker W/art﹕ Suspending all threads took: 19.779ms
07-10 16:57:28.898    1906-1913/com.symplyfyweb.gherghina.oldschoolwesternpoker W/art﹕ Suspending all threads took: 12.510ms
07-10 16:57:31.940    1906-1918/com.symplyfyweb.gherghina.oldschoolwesternpoker I/art﹕ Clamp target GC heap from 66MB to 64MB
07-10 16:57:32.352    1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker I/art﹕ Alloc sticky concurrent mark sweep GC freed 8(432B) AllocSpace objects, 0(0B) LOS objects, 1% free, 62MB/64MB, paused 1.468ms total 17.160ms
07-10 16:57:32.378    1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker I/art﹕ Clamp target GC heap from 66MB to 64MB
07-10 16:57:32.378    1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker I/art﹕ Alloc partial concurrent mark sweep GC freed 14(576B) AllocSpace objects, 0(0B) LOS objects, 1% free, 62MB/64MB, paused 889us total 19.090ms
07-10 16:57:32.444    1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker I/art﹕ Clamp target GC heap from 66MB to 64MB
07-10 16:57:32.444    1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker I/art﹕ Alloc concurrent mark sweep GC freed 8(12KB) AllocSpace objects, 0(0B) LOS objects, 1% free, 62MB/64MB, paused 789us total 57.650ms
07-10 16:57:32.451    1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker I/art﹕ Forcing collection of SoftReferences for 12MB allocation
07-10 16:57:32.501    1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker I/art﹕ Clamp target GC heap from 66MB to 64MB
07-10 16:57:32.502    1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker I/art﹕ Alloc concurrent mark sweep GC freed 11(288B) AllocSpace objects, 0(0B) LOS objects, 1% free, 62MB/64MB, paused 799us total 49.442ms
07-10 16:57:32.507    1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker E/art﹕ Throwing OutOfMemoryError "Failed to allocate a 13068012 byte allocation with 1263808 free bytes and 1234KB until OOM"
07-10 16:57:32.524    1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker I/art﹕ Alloc sticky concurrent mark sweep GC freed 5(448B) AllocSpace objects, 0(0B) LOS objects, 1% free, 62MB/64MB, paused 731us total 14.526ms
07-10 16:57:32.550    1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker I/art﹕ Clamp target GC heap from 66MB to 64MB
07-10 16:57:32.551    1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker I/art﹕ Alloc partial concurrent mark sweep GC freed 10(376B) AllocSpace objects, 0(0B) LOS objects, 1% free, 62MB/64MB, paused 954us total 19.113ms
07-10 16:57:32.664    1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker I/art﹕ Clamp target GC heap from 66MB to 64MB
07-10 16:57:32.665    1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker I/art﹕ Alloc concurrent mark sweep GC freed 3(96B) AllocSpace objects, 0(0B) LOS objects, 1% free, 62MB/64MB, paused 1.193ms total 108.749ms
07-10 16:57:32.675    1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker W/art﹕ Suspending all threads took: 9.507ms
07-10 16:57:32.675    1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker I/art﹕ Forcing collection of SoftReferences for 12MB allocation
07-10 16:57:32.770    1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker I/art﹕ Clamp target GC heap from 66MB to 64MB
07-10 16:57:32.770    1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker I/art﹕ Alloc concurrent mark sweep GC freed 3(96B) AllocSpace objects, 0(0B) LOS objects, 1% free, 62MB/64MB, paused 11.517ms total 93.336ms
07-10 16:57:32.775    1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker E/art﹕ Throwing OutOfMemoryError "Failed to allocate a 13068012 byte allocation with 1263992 free bytes and 1234KB until OOM"
07-10 16:57:32.777    1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker D/skia﹕ --- allocation failed for scaled bitmap
07-10 16:57:32.779    1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker D/AndroidRuntime﹕ Shutting down VM
    --------- beginning of crash
07-10 16:57:32.802    1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.symplyfyweb.gherghina.oldschoolwesternpoker, PID: 1906
    java.lang.OutOfMemoryError: Failed to allocate a 13068012 byte allocation with 1263992 free bytes and 1234KB until OOM
            at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
            at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
            at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:609)
            at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:444)
            at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:467)
            at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:497)
            at com.symplyfyweb.gherghina.oldschoolwesternpoker.PlayActivity.setBitmap(PlayActivity.java:97)
            at com.symplyfyweb.gherghina.oldschoolwesternpoker.PlayActivity.onClick(PlayActivity.java:112)
            at android.view.View.performClick(View.java:4780)
            at android.view.View$PerformClick.run(View.java:19866)
            at android.os.Handler.handleCallback(Handler.java:739)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5257)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

【问题讨论】:

  • 您可以使用 BitmapFactory.decodeResource: tinyurl.com/2f3rba7 并在不需要时对创建的位图调用回收。 (回收释放堆中的数据)。 developer.android.com/reference/android/graphics/…
  • 我用位图工厂方法编辑了我的帖子..但它给了我错误
  • 在 clearArrayList 中执行此操作并将 clearArrayList 移动到 onClick 的顶部。
  • 这不起作用,因为您在绘制视图之前回收位图并且它会给您一个错误。用户单击按钮时回收位图(在方法顶部) - 回收不必要的位图。
  • 所以在 clearArray 我应该只做 bitmap.recycle() ?

标签: java android memory memory-management


【解决方案1】:

你真的应该缓存你的图片,这样它们只需要加载一次。

这将非常简单,您所要做的就是在加载位图时检查它是否已经在缓存中,然后使用它。如果不是,则加载图像。这将阻止您多次加载资源。

HashMap<String, Integer> resCache = new HashMap<String, Integer>();
...
...
private void setBitmap(ImageView iv, int n) {
    String str = "img_" + numbers.get(n);
    int resID = -1;
    if  (resCache.containsKey(str)) {
        resID = resCache.get (str);
    } else {
        resID = getResources().getIdentifier(str, "drawable",  getPackageName());
        resCache.put (str, resID);
    }
    iv.setImageResource(resID);
}

【讨论】:

    【解决方案2】:
    // create second array list: 
    ArrayList<Bitmap> bitmaps = new ArrayList<Bitmap>();
    private void clearArrayList() {
        numbers.clear();
        for(Bitmap bitmap : bitmaps)
        {
            bitmap.recycle();
        }
        bitmaps.clear();
    }
    
    @Override
    public void onClick(View v) {
        clearArrayList();
        getRandomNumbers();
    
        setBitmap(card1, 0);
        setBitmap(card2, 1);
        setBitmap(card3, 2);
        setBitmap(card4, 3);
        setBitmap(card5, 4);
    }
    

    编辑:

    private void setBitmap(ImageView iv, int n) {
            String str = "img_" + numbers.get(n);
            Bitmap bitmap = BitmapFactory.decodeResource(getResources(), getResourceID(str, "drawable",
                    this));
            iv.setImageBitmap(bitmap);
            bitmaps.add(bitmap);
        }
    

    【讨论】:

    • 以及如何使用位图数组列表?
    • @xyz 我只为 clearArrayList 方法创建了位图数组列表。
    • @xyz 位图被添加到 setBitmap 中,当用户单击按钮时,先前的位图被释放(和免费数据)
    • 我试过这个,它也崩溃了。 vm中的内存是137mb
    • 你能粘贴logcat吗?
    【解决方案3】:

    除了回收位图之外,真正有帮助的一件事是,如果您不需要完整尺寸的位图,请不要加载它。例如,如果您尝试加载使用设备相机拍摄的图像,它们的分辨率可能比您能够在显示器上显示的分辨率高得多(例如,完整尺寸的图像可能是 2000 x 20000 像素和您可能正在尝试在 500 x 500 像素的 ImageView 中显示它)。全尺寸位图将占用更多内存空间,实际上,在缩小尺寸的图像视图上显示时,您将丢弃大量像素。

    如果要显示位图的 ImageView 没有全尺寸图像那么大,请尝试这篇 SO 帖子,了解如何减少位图的内存占用:

    How to scale bitmap to screen size?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-12
      • 2021-12-12
      • 1970-01-01
      • 2011-12-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多