【问题标题】:Out of memory error when using Google Maps API使用 Google Maps API 时出现内存不足错误
【发布时间】:2011-04-18 16:23:37
【问题描述】:

我这里有一个应用程序,它具有在地图上显示 POI 的功能。它只是一个 POI,并且仅在它实际位于可见屏幕区域内时才会绘制。它可以完美运行一段时间,但如果我玩放大和缩小和拖动,它最终会崩溃。根据 Logcat 的说法,原因始终是 OutOfMemory 错误。

起初,我认为这是 Google Maps API 的错误。经过一些研究并看到了一些 Romain Guy 的帖子,我有点确信我在我的应用程序上做了一些愚蠢的事情,这让我时不时地耗尽内存。 然后我在 Heap Analyzer (Eclipse) 上运行了一些更详细的测试,我发现即使我有 2+,有时 3+ 兆字节的可用内存,我仍然收到由 OutOfMemoryError 引起的那些烦人的强制关闭消息。大多数情况下,无论我还剩下多少,它在尝试分配一些 614kb 的内存块时都会崩溃。

这个问题在 Nexus One 2.2.1 和 HTC Evo 2.1 上经常发生。经过一些小测试,我在 G1 1.6 和三星 Galaxy S i9000 2.1 上都没有崩溃。但我不能确定 G1 和 Galaxy 经过更多测试后不会出现这个问题。

我只能想到一个内存碎片问题。我希望这个问题有解决方案。如果我能抓住这个错误并防止应用程序崩溃,我也会很高兴。

如果有帮助,这里是 logcat:

09-29 08:58:06.661: ERROR/dalvikvm-heap(1552): 648000-byte external allocation too large for this process.
09-29 08:58:06.661: ERROR/dalvikvm(1552): Out of memory: Heap Size=9991KB, Allocated=6980KB, Bitmap Size=14510KB
09-29 08:58:06.661: ERROR/(1552): VM won't let us allocate 648000 bytes
09-29 08:58:06.672: DEBUG/AndroidRuntime(1552): Shutting down VM
09-29 08:58:06.672: WARN/dalvikvm(1552): threadid=3: thread exiting with uncaught exception (group=0x4001b390)
09-29 08:58:06.672: ERROR/AndroidRuntime(1552): Uncaught handler: thread main exiting due to uncaught exception
09-29 08:58:06.681: ERROR/AndroidRuntime(1552): java.lang.OutOfMemoryError: bitmap size exceeds VM budget
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):     at android.graphics.Bitmap.nativeCreate(Native Method)
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):     at android.graphics.Bitmap.createBitmap(Bitmap.java:569)
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):     at com.google.android.maps.ZoomHelper.createSnapshot(ZoomHelper.java:422)
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):     at com.google.android.maps.ZoomHelper.beginZoom(ZoomHelper.java:186)
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):     at com.google.android.maps.MapView$2.onScaleBegin(MapView.java:371)
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):     at android.view.ScaleGestureDetector.onTouchEvent(ScaleGestureDetector.java:208)
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):     at com.google.android.maps.MapView.onTouchEvent(MapView.java:646)
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):     at android.view.View.dispatchTouchEvent(View.java:3709)
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:874)
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:924)
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:924)
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:924)
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):     at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1701)
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):     at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1116)
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):     at android.app.Activity.dispatchTouchEvent(Activity.java:2068)
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):     at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1685)
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):     at android.view.ViewRoot.handleMessage(ViewRoot.java:1708)
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):     at android.os.Handler.dispatchMessage(Handler.java:99)
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):     at android.os.Looper.loop(Looper.java:123)
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):     at android.app.ActivityThread.main(ActivityThread.java:4595)
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):     at java.lang.reflect.Method.invokeNative(Native Method)
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):     at java.lang.reflect.Method.invoke(Method.java:521)
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):     at dalvik.system.NativeStart.main(Native Method)

【问题讨论】:

  • 我从拥有操作系统版本 1.5、2.1 和 2.2 的用户那里收到了相同的错误报告。 Stacktrace 没有通过我的代码,所以我无法捕捉到这个错误 - 应用程序以 FC 结束。
  • 看起来确实是碎片问题。这就像我的应用程序有一些内存泄漏,将小块数据散布在我的堆内存区域中。我猜想这种行为可以在 Dalvik 的下一个版本中得到改进,因为它可能不是一个错误,但可以肯定它不是一个“好行为”,因为你实际上有内存但系统由于它的碎片而无法使用。好吧,我会继续努力看看能做些什么。
  • 我知道这个问题被问到现在已经一年多了,但是有针对这个问题开发的解决方案吗?我很好奇。提前致谢!

标签: android memory bitmap google-maps-api-3


【解决方案1】:

我遇到了同样的问题,在清单文件的应用程序标签下添加以下行

android:largeHeap = true 。这对我有用

【讨论】:

  • 它提高了崩溃率,但并不能完全解决问题。
  • 这基本上是一个备份解决方案,如果绝对没有任何工作。
【解决方案2】:

我一直遇到同样的问题,我用一些 System.GC 调用对代码进行了加盐处理,它似乎有点帮助,但这仍然会发生。

我还遇到了另一个问题,这可能与您捏缩放时地图似乎翻转并完全随机化有关。这往往发生在崩溃之前。

这一切都只发生在 HTC Desire 上,我相信它与 Nexus One 是同一部手机。 (在许多方面与 EVO 相似,EVO 也受此影响)。

注意:它在我们的 Arc-S、Galaxy V1、AVD 模拟器和华硕平板电脑上工作 100%。

【讨论】:

    【解决方案3】:

    在过去的一个月里,我时断时续地遇到了这个问题。我在代码中解决该问题的方法是强制 GC 清理我在 WeakReferences 中包装的未引用位图。这种方法可能对您不起作用,因为您在上面粘贴的崩溃似乎源自 MapView。无论如何,尝试在代码中的关键位置添加一些 System.gc() 调用并观察系统日志以查看 GC_EXPLICIT 消息是否指示大量对象/字节被释放。在我正在处理的代码中,我必须在我的 Adapter.getView() 方法的末尾添加一个 System.gc() 以确保在下次调用 getView() 时清除未使用的位图。这种方法似乎大大减少了我与 可怕的 java.lang.OutOfMemoryError: 位图大小超出 VM 预算崩溃。

    【讨论】:

    • 调用 System.gc() 不应该帮助 OOME。在首先尝试运行 GC 之前,VM 不会通过 OOME。此外,System.gc() 对碎片没有任何作用。
    • 这些 OOME 错误往往更频繁地发生在 Galaxy 系列的手机上,例如:Nexus One 和 Nexus S。我没有太多使用 Galaxy Nexus 来检查这个问题是否也更多地发生在这手机与其他手机相比。据我所知,抛出 GC 调用以清理内存并仔细编码是避免此问题的最佳方法。还可以捕获异常(作为 Throwable)并至少防止应用程序强制关闭。但不幸的是,我不确定这个问题是否有明确的解决方案......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-07
    • 2016-10-10
    • 1970-01-01
    • 1970-01-01
    • 2012-05-15
    • 2011-07-15
    • 1970-01-01
    相关资源
    最近更新 更多