谷歌地图api v2内存不足错误

我在我的应用程序中有一个巨大的内存问题。 我正在使用谷歌地图api v2与ClusterManager和自定义标记。 我通过调用markerOptions.icon(BitmapDescriptorFactory.fromBitmap(bitmap));来提供图像markerOptions.icon(BitmapDescriptorFactory.fromBitmap(bitmap)); 为每个标记基于其类别。 问题是:几个屏幕旋转后,我的应用程序崩溃,因为OOM错误:

 05-14 11:04:12.692 14020-30201/rokask.rideabike E/art﹕ Throwing OutOfMemoryError "Failed to allocate a 4194316 byte allocation with 1627608 free bytes and 1589KB until OOM" 05-14 11:04:12.722 14020-30201/rokask.rideabike E/AndroidRuntime﹕ FATAL EXCEPTION: GLThread 19179 Process: rokask.rideabike, PID: 14020 java.lang.OutOfMemoryError: Failed to allocate a 4194316 byte allocation with 1627608 free bytes and 1589KB until OOM at dalvik.system.VMRuntime.newNonMovableArray(Native Method) at android.graphics.Bitmap.nativeCreate(Native Method) at android.graphics.Bitmap.createBitmap(Bitmap.java:939) at android.graphics.Bitmap.createBitmap(Bitmap.java:912) at android.graphics.Bitmap.createBitmap(Bitmap.java:879) at com.google.maps.api.android.lib6.gmm6.ncia(Unknown Source) at com.google.maps.api.android.lib6.gmm6.ncla(Unknown Source) at com.google.maps.api.android.lib6.gmm6.ncla(Unknown Source) at com.google.maps.api.android.lib6.gmm6.nclb(Unknown Source) at com.google.maps.api.android.lib6.gmm6.ncbak.a(Unknown Source) at com.google.maps.api.android.lib6.gmm6.ncbas.a(Unknown Source) at com.google.maps.api.android.lib6.gmm6.nxa(Unknown Source) at com.google.maps.api.android.lib6.gmm6.nla(Unknown Source) at com.google.maps.api.android.lib6.gmm6.nlb(Unknown Source) at com.google.maps.api.android.lib6.gmm6.n.cv.f(Unknown Source) at com.google.maps.api.android.lib6.gmm6.n.cv.run(Unknown Source) 

我有一个LruCache对象与我的Bitmap s,这意味着我不重新创build它们,但重新使用它们。 我可以清楚地看到,每个Bitmap对象都是从caching中取出,而不是从其他地方取出。 但是,如果Bitmap尚未在caching中(第一次加载),我从我的应用程序的内部存储器中加载它,但它只有当Bitmap第一次被覆盖时才受欢迎。 我将LruCache的实例保留在保留的Fragment实例中,并在每次重新创buildActivity并将地图重新​​绘制时将其传递给我的自定义DefaultClusterRenderer<MyObject>对象。

这是我的DefaultClusterRenderer<MyItem>扩展名:

 public class DotRenderer extends DefaultClusterRenderer<Dot> { private final String internalStorageDir; private final LruCache<String, Bitmap> lruCache; public DotRenderer(Context context, GoogleMap googleMap, ClusterManager<Dot> clusterManager, LruCache<String, Bitmap> lruCache, String internalStorageDir) { super(context, googleMap, clusterManager); //this.bitmaps = bitmaps; this.internalStorageDir = internalStorageDir; this.lruCache = lruCache; } @Override protected void onBeforeClusterItemRendered(Dot mapObject, MarkerOptions markerOptions) { markerOptions.title(mapObject.getTitle()); String id = Integer.toString(mapObject.getTypeId()); // Bitmap bitmap = getBitmapFromMemCache(id); if (bitmap == null) { Log.d(MainActivity.LOG_TAG, "reading bitmap from storage."); Map.Entry<String, Bitmap> bitmapEntry = BitmapManager.getBitmapFromStorage(internalStorageDir, id); if (bitmapEntry != null) { markerOptions.icon(BitmapDescriptorFactory.fromBitmap(bitmapEntry.getValue())); addBitmapToMemCache(id, bitmapEntry.getValue()); } } else { Log.d(MainActivity.LOG_TAG, "reading bitmap from cache."); markerOptions.icon(BitmapDescriptorFactory.fromBitmap(bitmap)); } } private void addBitmapToMemCache(String key, Bitmap bitmap) { if (getBitmapFromMemCache(key) == null) { lruCache.put(key, bitmap); } } private Bitmap getBitmapFromMemCache(String key) { return lruCache.get(key); } } 

这是我的Activity中的代码,我开始加载地图(每次屏幕方向更改时执行此代码):

  ClusterManager<Dot> clusterManager = new ClusterManager<>(this, googleMap); clusterManager.setOnClusterItemInfoWindowClickListener( new ClusterManager.OnClusterItemInfoWindowClickListener<Dot>() { @Override public void onClusterItemInfoWindowClick(Dot dot) { int id = dot.getId(); String title = dot.getTitle(); Log.d(LOG_TAG, "clicked marker with id " + id + " and title " + title + "."); Intent infoWindowActivityIntent = new Intent(MainActivity.this, InfoWindowActivity.class); infoWindowActivityIntent.putExtra("dotId", id); infoWindowActivityIntent.putExtra("dotTitle", title); startActivity(infoWindowActivityIntent); } }); googleMap.setOnCameraChangeListener(clusterManager); googleMap.setOnInfoWindowClickListener(clusterManager); DotRenderer dotRenderer = new DotRenderer(getApplicationContext(), googleMap, clusterManager, lruCache, this.getFilesDir().toString()); clusterManager.setRenderer(dotRenderer); 

内存不断增加随着每一个屏幕旋转,我越放大地图(更多的标记显示)越多的内存添加到我的应用程序的堆时,我旋转屏幕,直到应用程序崩溃。

有时错误不是像上面那样,但是显示OOM发生在我的DefaultClusterRenderer<MyItam>扩展markerOptions.icon(BitmapDescriptorFactory.fromBitmap(bitmap));这一行markerOptions.icon(BitmapDescriptorFactory.fromBitmap(bitmap));

如果我禁用自定义标记图标(删除所有Bitmap相关的代码)内存问题消失。 请帮助我find导致此OOM出现的原因。

Solutions Collecting From Web of "谷歌地图api v2内存不足错误"

我遇到了这个问题,试图在演示模式下一次运行几个小时的应用程序。 无论我尝试了什么,30分钟后,我都会看到这个崩溃,没有可读的堆栈报告。

我尝试了系统gc(),分离片段,单身活动,更新到最新的谷歌播放服务,清除引用覆盖,附加地图生命周期的活动和不。 许多失败的尝试和很多挫折后,我终于find了一些工作。 这不是一个修复地图错误,但它保持我的应用程序崩溃:

  <application ... android:largeHeap="true"> 

好吧…我认为这应该工作…

添加googleMap.clear()只要你想重置地图。

希望这会帮助你。

这是谷歌地图V2的错误。 Google解决了一些问题。问题出在这里

要恢复此问题,您可以按照以下步骤操作:

XML会这样:

 <fragment android:id="@+id/frYourMap" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1" class="com.google.android.gms.maps.SupportMapFragment" /> 

以Google Map为例: `` GoogleMap atmFinderMap;

  1. 初始化map之前调用System.gc(); 的GetMap()清除();`

     if(GooglePlayServicesUtil.isGooglePlayServicesAvailable(getActivity()) == ConnectionResult.SUCCESS) { System.gc(); getMap().clear();} 

设置地图如下所示:

 SupportMapFragment fragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.frYourMap); atmFinderMap = fragment.getMap(); 
  1. 使用这个覆盖的方法:

     @Override public void onLowMemory() { super.onLowMemory(); System.gc(); } 

要获得更多信息可以看到这个答案