为什么我的 android 应用占用了太多内存?
Why my android app is consuming too much memory?
情况是这样的:
我有一个 Activity,它有一个工具栏、一个 Tablayout 和一个 View Pager(将包含 5 个片段)
在第一个片段中,我有一个布局,将包含一个默认片段,该片段将有一个包含两列的 Recycler View。这上面的每个元素都有一张从互联网上下载的图片(使用 Glide 并保存在缓存中),当用户点击 holder(列表的一个元素)时,会将 'layout container' 上的默认片段更改为另一个这将有一个新的 Recycler View,其中包含使用 Glide 从 Internet 下载的图像。类似于 Instagram 搜索页面。
我认为 Glide 是问题所在,但我注释了所有代码,当我 运行 模拟器上的应用程序时,它消耗了 89 MB 的 RAM 或更少。
额外信息
- 任何片段中 RView 上的每个元素都是通过使用 Volley 下载 JSONArray 创建的,我将请求放入 MySingleton 队列并将上下文定义为 getContext()(我应该使用 getActivity().当代码来自片段时,ApplicationContext() 而不是 getContext()?)
(在 Activity 内的视图寻呼机内的片段内)
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 监视器和 'Jump Java Heap' 选项来查看它是如何管理内存的,主要编号在 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.
好吧,我想我找到了解决方案并且我已经总结了这些事情:
- 使用 .jpg 格式的可绘制对象或任何大于 150kb 的文件都会占用内存。就我而言,我使用非常大的图像作为背景,在回收站视图中使用小图像但大于 200kb。那些正在杀死拉姆。
- 最好在调用 Volley Request 时使用片段的本地上下文 (getContext()) 并将其放入 MySingleton 队列。
- recyclerViews 上的 Holder 应该是内部静态的 classes,因为你要重新使用它们,这是节省内存的好方法。
- 如果您在每个 Holder 上使用 Glide 下载图片并且有一些 link 空的,您应该清理 ImageView:
Glide.clear(ImgView);
- 为调用 SharedPreferences 创建对象不是一个好主意。最好使用全局 class,它使用一个上下文(包含所有片段的 activity)并从那里调用 SharedPreferences。类似于:
MyCallerClass.getInstance().getPrefsDataOfOuser();
所有这些都是我这些天得出的结论...现在我的应用程序使用 50mb 的内存下载带有滑动的图像和 80mb 或 90mb 的实时搜索最大...
情况是这样的: 我有一个 Activity,它有一个工具栏、一个 Tablayout 和一个 View Pager(将包含 5 个片段)
在第一个片段中,我有一个布局,将包含一个默认片段,该片段将有一个包含两列的 Recycler View。这上面的每个元素都有一张从互联网上下载的图片(使用 Glide 并保存在缓存中),当用户点击 holder(列表的一个元素)时,会将 'layout container' 上的默认片段更改为另一个这将有一个新的 Recycler View,其中包含使用 Glide 从 Internet 下载的图像。类似于 Instagram 搜索页面。
我认为 Glide 是问题所在,但我注释了所有代码,当我 运行 模拟器上的应用程序时,它消耗了 89 MB 的 RAM 或更少。
额外信息
- 任何片段中 RView 上的每个元素都是通过使用 Volley 下载 JSONArray 创建的,我将请求放入 MySingleton 队列并将上下文定义为 getContext()(我应该使用 getActivity().当代码来自片段时,ApplicationContext() 而不是 getContext()?)
(在 Activity 内的视图寻呼机内的片段内)
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 监视器和 'Jump Java Heap' 选项来查看它是如何管理内存的,主要编号在 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.
好吧,我想我找到了解决方案并且我已经总结了这些事情:
- 使用 .jpg 格式的可绘制对象或任何大于 150kb 的文件都会占用内存。就我而言,我使用非常大的图像作为背景,在回收站视图中使用小图像但大于 200kb。那些正在杀死拉姆。
- 最好在调用 Volley Request 时使用片段的本地上下文 (getContext()) 并将其放入 MySingleton 队列。
- recyclerViews 上的 Holder 应该是内部静态的 classes,因为你要重新使用它们,这是节省内存的好方法。
- 如果您在每个 Holder 上使用 Glide 下载图片并且有一些 link 空的,您应该清理 ImageView:
Glide.clear(ImgView);
- 为调用 SharedPreferences 创建对象不是一个好主意。最好使用全局 class,它使用一个上下文(包含所有片段的 activity)并从那里调用 SharedPreferences。类似于:
MyCallerClass.getInstance().getPrefsDataOfOuser();
所有这些都是我这些天得出的结论...现在我的应用程序使用 50mb 的内存下载带有滑动的图像和 80mb 或 90mb 的实时搜索最大...