我这里有一个应用程序,它具有在地图上显示POI的功能。它只是一个POI,只有当它实际位于可见屏幕区域内时才会被绘制。它可以完美地工作一段时间,但如果我在放大和缩小和拖动时玩,它最终会崩溃。根据Logcat,原因始终是OutOfMemory错误。
起初,我认为这是Google Maps API上的一个错误。经过一些研究和看到一些Romain Guy的帖子,我有点确信我在我的应用程序上做了一些愚蠢的事情让我不时耗尽内存。 然后我用Heap Analyzer(Eclipse)运行了一些更详细的测试,我看到即使我有2 +,有时3+兆字节的可用内存,我仍然得到由OutOfMemoryError引起的恼人的Force Close消息。大多数时候,无论我剩下多少,它都会在尝试分配大约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)
答案 0 :(得分:1)
过去一个月我一直在讨论这个问题。我在代码中解决这个问题的方法是强制GC清理我在WeakReferences中包含的未引用的位图。这种方法可能不适合您,因为您粘贴在上面的崩溃似乎源自MapView。无论如何,尝试在代码中的关键位置进行一些System.gc()调用,并观察系统Log以查看GC_EXPLICIT消息是否指示释放了大量对象/字节。在我正在处理的代码中,我必须在我的Adapter.getView()方法的末尾添加一个System.gc(),以确保在下次调用getView()时清除未使用的位图。这种方法似乎大大减少了我的使用时间 dreaded java.lang.OutOfMemoryError:位图大小超过VM预算崩溃。
答案 1 :(得分:1)
我一直有这个完全相同的问题,我用一些System.GC调用来腌制代码,它似乎有点帮助,但这仍然会发生。
我还遇到了另一个问题,可能与地图似乎翻转时相关,当你捏缩放时,它会随机变化。这有时会在崩溃之前发生。
这一切只发生在HTC Desire上,我认为它与Nexus One的手机相同。 (在许多方面类似于EVO,它也受到影响)。
注意:我们的Arc-S,Galaxy V1,AVD仿真器和华硕平板电脑的工作效率为100%。
答案 2 :(得分:1)
我遇到了同样的问题,在应用程序标记
下的清单文件中添加以下行android:largeHeap = true。这对我有用