【问题标题】:My Android app is taking too much memory我的 Android 应用占用了太多内存
【发布时间】:2014-09-20 20:27:56
【问题描述】:

我有什么

我有一个包含一些活动的应用程序。每个活动都有一些 EditTexts、ImageViews、ImageButtons 并且也可以访问 SharedPreferences。

我的问题

每当我从一个活动移动到另一个活动时,例如从启动屏幕到登录屏幕,然后再到主活动,我的堆大小都会大幅增长。它甚至达到 142 MB,并且由于 OutOfMemory 错误,我的应用程序在许多设备上崩溃。

我已经做了什么

我已经在 onPause() 方法中对 null 进行了所有引用,它在一定程度上减少了堆大小,但始终保持在 80 MB 左右。我怀疑主要问题出在可绘制对象上,因为我也遇到了这个错误。

请帮我解决一些问题。我应该怎么做才能减少内存使用?

【问题讨论】:

  • 你在用drawable做什么?请出示该代码。
  • 您是否在使用任何第三方库?
  • 当它崩溃时,检查 OutOfMemory 错误发生的位置并在此处发布该代码。
  • @VenomVendor 是的,我正在使用两个库,一个是 Zip4j,另一个是 SwipeListView。

标签: android android-activity memory-leaks heap-memory


【解决方案1】:

首先,我强烈建议您使用 MAT 来分析堆的内容。 http://android-developers.blogspot.be/2011/03/memory-analysis-for-android.html

确保您提供适当版本和大小的可绘制对象(mdpi、hdpi、xhpdi...)

【讨论】:

    【解决方案2】:

    如果您确定所有引用在 java 端都设置为 null,那么它们可能是 Drawables 的问题,我发布了一个简单的解决方案,只需将该代码放在您的活动类中,然后 onDestroy 调用该代码它将释放可绘制对象占用的所有内存。

    protected void unbindDrawables(View view) {
        if (view != null) {
            if (view.getBackground() != null) {
                view.getBackground().setCallback(null);
            }
            if (view instanceof ViewGroup && !(view instanceof AdapterView)) {
                for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
                    unbindDrawables(((ViewGroup) view).getChildAt(i));
                }
                ((ViewGroup) view).removeAllViews();
            }
    
        }
    
    }
    

    如何使用此方法。 查看rootView;

        @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        rootView = getLayoutInflater().inflate(R.layout.splashactivity,
                null);
        setContentView(rootView);
    

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    
    
        unbindDrawables(rootView);
        rootView = null;
        System.gc();
    
    }
    

    【讨论】:

    • 我已将您的代码添加到我的所有活动中,但堆大小仍约为 80 MB。你能添加一个更好的方法来释放内存并减少堆大小吗? PS - 我的一项活动中还有一些片段和 ViewPager。
    • 你调用了finish();这仅在调用 ondestory 时才有效,并且仅在您销毁活动时才会发生。您也可以在 onPause 中执行此操作,但这需要您再次设置内容视图 onResume
    • 第二次使用分配跟踪器查看占用内存的内容。第三次在 unbinddrawablea 方法中输入一个日志,看看它是否被调用,最后设置的内容视图等于一个膨胀的布局,如果发生这种情况,不使用 r.layout.yourlayout unbinddrawables 将不起作用
    • 我在使用意图从一个活动移动到另一个活动时调用了finish()。我也应该以某种方式移除碎片吗?
    • 我也在使用共享首选项,我应该在使用后以某种特定的方式释放它吗?
    猜你喜欢
    • 1970-01-01
    • 2017-09-01
    • 2013-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-14
    • 1970-01-01
    相关资源
    最近更新 更多