Android 内存不足预防

发布于 2024-10-31 09:19:15 字数 147 浏览 0 评论 0原文

我有一个列表,显示从网络上即时下载的缩略图(小图像)。 在某个时刻,进程会耗尽内存。 我如何知道可用内存即将耗尽,以便我可以停止下载更多图像?

我想提前知道,以免处于失忆的边缘。

笔记: 这不是内存泄漏,只是下载了大量位图。

谢谢。

I have a list that shows thumbnails (small images) downloaded on the fly from the web.
At some point, the process runs out of memory.
How can I tell that the free memory is about to run off, so I can stop downloading more images?

I would like to know it in advance in order not to be on the edge of out of memory.

Note:
It is not a memory leak, just lots of downloaded bitmaps.

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

卷耳 2024-11-07 09:19:15

1)你必须是你自己的浏览器。

将您的拇指下载到 SDCard,而不是将它们保存在 RAM 中。在保存它们之前缩小/旋转它们,这样当您下次需要加载它们时,可以从 SDCard“免费”加载它们,而不是从互联网上昂贵地加载。 (即:像任何浏览器一样,使用本地文件缓存)。

释放您可能为此创建的任何临时位图对象。

了解如何使用“inSampleSize”参数以低于原始分辨率的分辨率解压位图。

如果您编写的文件以图像扩展名(.jpg 等)结尾,它们将出现在图库中,因此不要使用明显的图像文件名来保存您的拇指。

2) 创建分层缓存系统(Bitmap > SDCard > Internets)。

当您解压缩略图时,将其保存在 SoftReference 缓存中。如果您需要使用该缩略图,请从缓存中获取。如果虚拟机需要更多内存,您的 SoftReference 实例可能会返回 null。

如果您从位图缓存中获取 null,请检查您是否已将 URL 放在 SD 卡上并将其从那里加载到位图缓存中。

如果从文件系统中获取 null,则从互联网下载图像并将其保存到 SDCard 并将其粘贴到位图缓存中。

3) 释放未使用的资源。

以同样的方式,确保一旦视图离开屏幕就从它们所放置的视图中清除位图(如果您的视图位于 ListView 或其他基于适配器的元素中,则这本质上是“免于”回收View elements)——但是,如果您使用位图实例化了 ImageView,并且它们没有立即显示在屏幕上,那么您可能会浪费堆。

您可以简单地在 ImageView 上调用 setImageBitmap(null); ,对位图的引用将被删除(这样,如果唯一的引用是未使用的 SoftReference)。

4) 注意您所在的线程。

记住,您必须从非 UI 线程下载位图(我们使用 Service 实例充当意图请求队列),并且您 >必须仅在 UI 线程中将位图附加到 View 实例。

您需要创建一个良好的排队系统,将所有内容从 UI 线程加载到位图缓存中,然后使用处理程序告诉您的位图缓存填充 UI 线程上的 ImageView。

5) 注意您的下载队列。

如果您像我们一样,同时拥有拇指全尺寸图像,则需要手动使用优先级队列将图像请求放在拇指请求之前,或者使用两种不同的服务(即将它们单独的意图排队)来下载拇指与完整图像。

否则,您可能会在一个充满拇指下载的屏幕上排队,但直到所有拇指完成后才响应完整图像。

6) 询问系统你有多少RAM。

  Debug.MemoryInfo memoryInfo = new Debug.MemoryInfo();
  Debug.getMemoryInfo(memoryInfo);

7)“onLowMemory()”没有达到您的预期。

它适用于当用户在手机上运行太多应用程序并且操作系统需要从所有正在运行的应用程序恢复物理内存时。

这与耗尽应用程序 VM 堆完全不同,就像您通过加载太多位图轻松做到的那样。

据我所知,您不会收到警告,您只会崩溃(尽管您可以通过上述调用跟踪内存信息)。

希望这有助于尝试使从互联网下载和显示拇指变得聪明一些。

米格

1) You have to be your own browser.

Download your thumbs to the SDCard rather than keeping them in RAM. Shrink/rotate them before you save them so that when you next need to load them the load is "free" from the SDCard instead of expensive from the internets. (Ie: like any browser, use a local file cache).

Release any interim Bitmap objects you may create to do this.

Learn how to use the "inSampleSize" param to unpack Bitmaps at less than original resolution.

If the files you write end in an image extension (.jpg, etc) they will appear in the Gallery, so don't save your thumbs with obvious image filenames.

2) Create a tiered cache system (Bitmap > SDCard > Internets).

When you unpack a thumbnail, save it in a SoftReference cache. If you need to use that thumbnail, ask for it from the cache. If the VM needed more memory, your SoftReference instance may return null.

If you get null from your bitmap cache, then check to see if you've already put your url on the SD card and load it into the bitmap cache from there.

If you get null from your filesystem, then go download the image from the internet and save it to SDCard and stick it in your bitmap cache.

3) Release resources that aren't being used.

In the same way, make sure you clear the Bitmaps from the Views they have been placed in as soon as the View is offscreen (if your Views live in a ListView or other Adapter-based element, this is essentially "free" from recycling the View elements) -- However, if you have ImageViews instantiated with Bitmaps and they're not immediately displayed on the screen, you're probably wasting heap.

You can simply call setImageBitmap(null); on an ImageView and the reference to the Bitmap will be dropped (so that if the only ref is the SoftReference when it's not being used).

4) Pay attention to what thread you are in.

Remember, you must download bitmaps from a non-UI thread (we use a Service instance to act as a queue of intent requests), and you must attach bitmaps to View instance only in the UI thread.

You'll need to create a good queued system to load everything into your bitmap cache off the UI thread and then use a Handler to tell your bitmap cache to fill ImageViews on the UI thread.

5) Pay attention to your download Queues.

If you're like us and you have both thumbs and full-sized images, you need to either manually use a priority queue to put your image requests before you thumb requests, or use two different Services (that enqueue their separate Intents) to download thumbs vs full images.

Otherwise you might queue up a screen full of thumb downloads but not respond with a full image until after all of the thumbs complete.

6) Ask the system how much RAM you have.

  Debug.MemoryInfo memoryInfo = new Debug.MemoryInfo();
  Debug.getMemoryInfo(memoryInfo);

7) "onLowMemory()" doesn't do what you expect.

It is for when the user is running too many applications on the phone and the OS needs to recover physical memory from all of the running apps.

This is totally separate from running out of application VM heap like you'll easily do by loading too many bitmaps.

To the best of my knowledge you will not get a warning, you'll just crash (tho you can track memory info with the above call).

Hope that helps with trying to make something smart about downloading and displaying thumbs from the internets.

mig

梦里°也失望 2024-11-07 09:19:15

我使用 SoftReference 来保存位图对象。该列表只需要当前可见的图像。因此,我永远不需要担心空间不足。

缺点是,当我看到图像时,向下滚动(导致一些软引用清除位图),然后再次滚动回同一位置 - 图像再次下载:(

此外,软引用清除得非常快。我希望它们可以将内部位图保存更长时间。

I use SoftReference to hold the bitmap objects. The list only needs the current visible images. Thus, I never need to worry about running out of space.

The minus is that when I see the images, scroll down (causing some SoftReferences to clear the Bitmaps), then scroll back again to the same place - the images get downloaded again :(

Also, the SoftReferences get cleared very fast. I would expect them to save the inner bitmap longer.

我是有多爱你 2024-11-07 09:19:15

创建位图时,您应该使用 BitmapFactory.OptionsinSampleSize 选项。

另外,Android:图库中内存不足异常 对我检查可用内存很有用。

You should use inSampleSize option of BitmapFactory.Options while creating the bitmaps.

Also, some of the tips in Android: out of memory exception in Gallery has been useful for me in keeping a check on the memory available.

空心空情空意 2024-11-07 09:19:15

您可以覆盖 Activity 的 onLowMemory() 自定义处理此类场景的方法

You can over-ride the Activity's onLowMemory() method for custom handling such scenarios

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文