使用 Google Maps API 时出现内存不足错误
我这里有一个应用程序,具有在地图上显示 POI 的功能。它只是一个 POI,并且只有当它实际上位于可见屏幕区域内时才会被绘制。它可以完美运行一段时间,但如果我放大、缩小和拖动,它最终会崩溃。根据 Logcat 的说法,原因始终是 OutOfMemory 错误。
起初,我以为这是 Google Maps API 上的一个错误。经过一番研究并查看了一些 Romain Guy 的帖子后,我有点确信我在我的应用程序上做了一些愚蠢的事情,导致我时不时地耗尽内存。 然后我使用堆分析器(Eclipse)运行了一些更详细的测试,我发现即使我还有 2+,有时 3+ 兆字节的可用内存,我仍然收到由 OutOfMemoryError 引起的那些恼人的强制关闭消息。大多数时候,当尝试分配一些 614kb 内存块时,无论我还剩下多少,它都会崩溃。
此问题在 Nexus One 2.2.1 和 HTC Evo 2.1 上经常发生。经过一些小测试后,我在 G1 1.6 和 Samsung 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)
I have an application here that has a feature of showing a POI on the map. It's only one POI and it is only drawn when it's actually within the visible screen area. It works perfectly for a while but if I play around zooming in and out and dragging, it will eventually crash. According to Logcat, the reason is always an OutOfMemory error.
At first, I thought it was a bug on the Google Maps API. After some researching and seeing some Romain Guy posts, I was kind of convinced that I had done something stupid on my app that kept me running out of memory from time to time.
Then I ran some more detailed tests with Heap Analyzer (Eclipse) on and I saw that even though I had 2+, sometimes 3+ megabytes left of free memory, I was still getting those annoying Force Close messages caused by OutOfMemoryError. Most of the times it crashes when trying to allocate some 614kb chunk of memory regardless of how much I have left.
This problem happens a lot on Nexus One 2.2.1 and on HTC Evo 2.1. After some little testing, I got no crash neither on G1 1.6 nor Samsung Galaxy S i9000 2.1. But I cannot say for sure the G1 and Galaxy will not show this problem after more testing.
I can only think of a memory fragmentation problem. I hope this problem has a solution. I will also be glad if I can just catch this error and prevent the app from crashing.
If it helps, here's the 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)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
过去一个月我一直断断续续地遇到这个问题。我在代码中解决该问题的方法是强制 GC 清理我包装在 WeakReferences 中的未引用位图。这种方法可能不适合您,因为您上面粘贴的崩溃似乎源自 MapView。无论如何,尝试在代码的关键位置进行一些 System.gc() 调用,并观察系统日志以查看 GC_EXPLICIT 消息是否指示释放了许多对象/字节。在我正在处理的代码中,我必须在 Adapter.getView() 方法的末尾添加 System.gc(),以确保下次调用 getView() 时清除未使用的位图。这种方法似乎大大减少了我与
可怕的 java.lang.OutOfMemoryError:位图大小超出 VM 预算崩溃。
I have been running into this problem on and off for the past month. The way I've worked around the issue in my code is by forcing the GC to clean up unreferenced bitmaps that I have wrapped in WeakReferences. This approach might not work for you since the crash that you pasted above seems to originate in the MapView. Regardless, try to sprinkle some System.gc() calls in key locations in your code and watch the system Log to see if the GC_EXPLICIT messages indicate a lot of objects/bytes freed. In the code I'm working on I've had to add a System.gc() at the end of my Adapter.getView() method to ensure that unused bitmaps are cleaned up by the next time getView() is called. This approach seems to have drastically reduced my run in with the
dreaded java.lang.OutOfMemoryError: bitmap size exceeds VM budget crash.
我一直遇到这个完全相同的问题,我用一些 System.GC 调用对代码加盐,它似乎有一点帮助,但这种情况仍然发生。
我还遇到了另一个问题,该问题可能与当您捏缩放时地图似乎翻转并变得随机有关。有时,这种情况往往会在事故发生前发生。
这一切只发生在 HTC Desire 上,我相信它与 Nexus One 是同一款手机。 (在很多方面与 EVO 类似,EVO 也受到了这个问题的困扰)。
注意:它在我们的 Arc-S、Galaxy V1、AVD 模拟器和华硕平板电脑上运行 100% 正常。
I have been having this EXACT same problem, I salted the code with some System.GC calls and it seemed to help a little bit, but this still happens.
I am also getting another problem which might be related where the map seems to flip out and go all random when you pinch zoom. This tends to happen sometimes before a crash.
This is all only happening only on an HTC Desire which I believe is the same phone as the Nexus One under the hood. (and similar in many ways to the EVO which also suffers from it).
Note: It is working 100% fine on our Arc-S, Galaxy V1, AVD emulator and Asus tablet.
我遇到了同样的问题,在应用程序标签 android:largeHeap = true 下的清单文件中添加以下行
。这对我有用
I had the same problem , add the following line in manifest file under application tag
android:largeHeap = true . This worked for me