为什么我的安卓应用程序会消耗太多内存?

3
情况是这样的: 我有一个Activity,其中包含一个工具栏、一个选项卡布局和一个View Pager(其中包含5个片段)。
在第一个片段中,我有一个布局,其中包含一个默认片段,该片段将包含一个带有两列的Recycler View。每个元素都有一个从互联网上下载的图像(使用Glide并保存在缓存中),当用户单击列表中的某个元素时,将会将此默认片段更改为“布局容器”上的另一个片段,该片段将包含一个使用Glide从互联网上下载的新图像的Recycler View。类似于Instagram搜索页面。
我以为Glide是问题所在,但我注释了所有代码,当我在模拟器上运行应用程序时,它会消耗大约89 MB的RAM。
额外的信息:
- 在任何片段内部的RView中的每个元素都是通过使用Volley下载JSONArray创建的,我将请求放在MySingleton队列中,并将上下文定义为getContext()(当代码来自片段时,我应该使用getActivity().ApplicationContext()而不是getContext()吗?)
(位于View Pager内部的片段内)
MySingleton.getInstance(getContext()).addToRequestQueue(req);

然后它会下载图片的URL并使用Glide在视图上显示。
if(holder.publication.getPicture() != null ){
        Glide.with(holder.ctx).load(holder.publication.getPicture()).diskCacheStrategy(DiskCacheStrategy.ALL).centerCrop().into(holder.picture_imgView);
    }
  • 我没有使用静态变量。

  • 此外,我从 Recycler View 元素中删除了所有动画,但仍然很慢。

  • 我使用 Android Monitor 和“跳转 Java 堆”选项来查看内存管理情况,主要数字在 Byte[] 上(我不理解使用这个工具)。

非常感谢!

更新: 我的日志上总是打印出这个:

W/ViewRootImpl: Dropping event due to no window focus: KeyEvent { action=ACTION_DOWN, keyCode=KEYCODE_BACK, scanCode=0, metaState=0, flags=0xc8, repeatCount=1, eventTime=18009881, downTime=18009352, deviceId=-1, source=0x101 }

I/Choreographer: Skipped 98 frames!  The application may be doing too much work on its main thread.

我感觉你下载图片时,内存使用情况非常正常。 - Nabin
有时候这个值会增加到120或130兆字节,但我想我终于解决了它。看起来问题出在可绘制资源上,它们太大了。我会继续分析以找到最终的解决方案。 - Jose Flavio Quispe Irrazábal
1个回答

6

好的,我认为我找到了解决办法,并得出以下结论:

  • 使用 .jpg 格式或大于 150kb 的文件作为 drawable 将会占用内存。在我的情况下,我使用非常大的图像作为背景和一些大小超过 200kb 的图像在 Recycler View 上,这些都会消耗 RAM。
  • 当调用 Volley 请求并将其放置在 MySingleton 队列中时,最好使用片段的本地上下文 (getContext())。
  • Recycler View 中的 Holder 应该是静态内部类,因为你会重复使用它们,这是节省内存的好方法。
  • 如果你在每个 Holder 中都使用 Glide 下载图像,并且有一些链接为空,你应该清除 ImageView: Glide.clear(ImgView);
  • 创建对象以调用 SharedPreferences 不是一个好主意。最好使用一个全局类,该类使用一个上下文 (包含所有片段的活动) 并从那里调用 SharedPreferences。例如:MyCallerClass.getInstance().getPrefsDataOfOuser();

这些都是我这些日子得出的结论...现在我的应用程序使用 50MB 的内存下载图片与 Glide,实时搜索时最多使用 80MB 或 90MB...


我有类似的问题,但我没有使用任何大图片作为背景。我猜你的解决方案最大的部分是关于使用较小的图片,其他建议帮了多少忙? - Tony
1
嗨,@Tony! 是的,我遇到的主要问题是我使用作为背景的大型图像资源,我必须对我的答案进行一些快速修复。关于上下文的使用,这与它们可能产生的引用和泄漏有关。您不应将Activity或Fragment(或任何其他Android组件)上下文用作单例的引用,因为单例将在整个应用程序中长时间存在,而活动将以某种方式死亡,该引用将导致内存泄漏。此文章更详细:https://medium.freecodecamp.org/mastering-android-context-7055c8478a22 - Jose Flavio Quispe Irrazábal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接