【问题标题】:Out of Memory Picasso Lib内存不足毕加索图书馆
【发布时间】:2014-10-29 17:24:56
【问题描述】:

我正在开发一个通过 lib Picasso 加载大量图像的应用程序。当我浏览应用程序时,应用程序突然崩溃,内存不足。 我已经尝试做一些事情来避免这种问题,但没有成功。

如果有人可以帮助我,我会很高兴。

代码下方:

java.lang.RuntimeException: Unable to start activity 
ComponentInfo{com.codal.whatsee/com.codal.whatsee.fragmentactivity.ItemPostFragmentActivity}: android.view.InflateException: Binary 
XML file line #55: Error inflating class <unknown>
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2217)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2266)
at android.app.ActivityThread.access$800(ActivityThread.java:145)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1206)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5141)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:611)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.view.InflateException: Binary XML file line #55: Error inflating class <unknown>
at android.view.LayoutInflater.createView(LayoutInflater.java:620)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:696)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:755)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:758)
at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
at android.view.LayoutInflater.inflate(LayoutInflater.java:353)
at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:343)
at android.app.Activity.setContentView(Activity.java:1929)
at com.codal.whatsee.fragmentactivity.ItemPostFragmentActivity.onCreate(ItemPostFragmentActivity.java:150)
at android.app.Activity.performCreate(Activity.java:5231)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2171)
... 11 more
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.constructNative(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at android.view.LayoutInflater.createView(LayoutInflater.java:594)
... 23 more
Caused by: java.lang.OutOfMemoryError
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:594)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:429)
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:840)
at android.content.res.Resources.loadDrawable(Resources.java:2208)
at android.content.res.TypedArray.getDrawable(TypedArray.java:602)
at android.widget.ImageView.<init>(ImageView.java:129)
at android.widget.ImageView.<init>(ImageView.java:119)
at com.codal.whatsee.utils.SquareImageView.<init>(SquareImageView.java:13)
... 26 more

OBS:这个问题不仅发生在这个类中,而且在任何其他类中也会发生。

【问题讨论】:

  • 导致OutOfMemoryError 的泄漏可以在任何地方。失败和崩溃的分配可能是无辜的。只有你可以帮助自己解决这个问题。您需要学习使用 Eclipse MAT 之类的堆分析器并找出泄漏的位置。
  • 显然,当您尝试从 XML 加载 ImageView 中的大图像时,会发生 OutOfMemory,至少这是堆栈跟踪所暗示的。如果是这样 - 毕加索与它无关。
  • @Egor 这是不正确的,这就是为什么OutOfMemoryErrors 调试起来如此棘手。毕加索很可能是罪魁祸首。它可能会用完大部分内存,然后一个无辜的ImageView 出现并以少量分配使应用程序崩溃。
  • @KevinKrumwiede,是的,这是真的,错过了这一点。感谢您的关注!
  • 我已经尝试在 Picasso 加载图像时跳过内存缓存,但是应用程序仍然崩溃。我什至尝试调试和分析堆,但没有成功。占用更多内存的对象是 byte[]。有什么办法可以清理这个物体吗?我会再次尝试做堆分析器,如果其他人知道如何解决这个问题,我将不胜感激。

标签: android memory out


【解决方案1】:

这听起来很像您的应用程序正在泄漏内存,而图像解码只是填充堆的最后一个操作。您应该使用 android DDMS 工具并在短暂使用后创建应用程序的堆转储。如果您在转储中看到许多活动或片段,您应该尝试找出哪些对象仍然持有对它们的引用。

以下是开发者网站的相关页面: https://developer.android.com/tools/debugging/debugging-memory.html

【讨论】:

  • 谢谢,我去看看。
【解决方案2】:

您可能会因为以下原因而出现 OOM:

  1. 您正在执行一些持续需要大量内存的操作。就像 Picasso Lib 获取使用位图操作的大图像/位图

    • Picasso 在获取图像时使用 fit() 或 resize() 方法。 ReferenceLink
  2. 内存泄漏:您没有使之前分配的对象符合垃圾回收 (GC) 条件

    • 使用内存分析器工具进行转储检查对象泄漏的位置。
  3. 处理大型位图。缩放和位图操作从堆中获取内存。

我遇到了这个链接。它可能会帮助你:Link

【讨论】:

    【解决方案3】:

    在处理图像和位图时,您可能会遇到这样的异常。在目前的情况下,内存不足似乎是由于加载了消耗可用内存并产生问题的大/大图像。

    幸运的是 picasso lib 提供了一个缩小图像的选项,这样它就不会消耗太多内存,从而降低出现内存不足异常的机会。

    看看下面这段代码对你有没有帮助。

    Picasso.with(context).load(file).resize(sizeToScaleDown, sizeToSacleDown).onlyScaleDown().into(imageView);
    

    注意:onlyScaleDown() 函数仅在您还使用了 resize() 函数时才有效。在没有 resize() 函数的情况下使用 onlyScaleDown() 函数会导致异常。

    【讨论】:

      【解决方案4】:

      Android 4.2 和 4.3 不会为位图释放内存,除非您使用位图完成活动或回收它 (Bitmap.recycle())。有关详细分析,请参阅Android Bitmap Memory Analysis - Part 3. API Version Comparison。在 Android 4.3 中,您还需要从视图层次结构中移除图像视图。

      因此,如果您有一个应用程序可以在其中建立深度导航历史并使用 Picasso,那么您迟早会耗尽内存,因为 Picasso 不跟踪对位图的引用,因此无法为它们调用 Bitmap.recycle()

      我们遇到了类似的问题,最后切换到 Facebook 的 Fresco library,它非常详细地跟踪参考。因此,它的使用也更加复杂,但它得到了回报。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-10-02
        • 1970-01-01
        • 2014-10-10
        • 2016-04-18
        • 1970-01-01
        • 2020-02-22
        • 1970-01-01
        • 2014-08-21
        相关资源
        最近更新 更多