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

Android 谷歌地图api v2内存不足错误,android,bitmap,out-of-memory,google-maps-android-api-2,markerclusterer,Android,Bitmap,Out Of Memory,Google Maps Android Api 2,Markerclusterer,我的应用程序内存严重问题。我正在使用带有ClusterManager和自定义标记的google map api v2。我通过调用markerOptions.icon(BitmapDescriptorFactory.fromBitmap(位图)),提供一个图像。问题是:在多次屏幕旋转后,我的应用程序因OOM错误而崩溃: 05-14 11:04:12.692 14020-30201/rokask.rideabike E/art﹕ Throwing OutOfMemoryError "Failed

我的应用程序内存严重问题。我正在使用带有
ClusterManager
和自定义标记的google map api v2。我通过调用
markerOptions.icon(BitmapDescriptorFactory.fromBitmap(位图)),提供一个图像。问题是:在多次屏幕旋转后,我的应用程序因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.n.c.i.a(Unknown Source)
        at com.google.maps.api.android.lib6.gmm6.n.c.l.a(Unknown Source)
        at com.google.maps.api.android.lib6.gmm6.n.c.l.a(Unknown Source)
        at com.google.maps.api.android.lib6.gmm6.n.c.l.b(Unknown Source)
        at com.google.maps.api.android.lib6.gmm6.n.c.b.ak.a(Unknown Source)
        at com.google.maps.api.android.lib6.gmm6.n.c.b.as.a(Unknown Source)
        at com.google.maps.api.android.lib6.gmm6.n.x.a(Unknown Source)
        at com.google.maps.api.android.lib6.gmm6.n.l.a(Unknown Source)
        at com.google.maps.api.android.lib6.gmm6.n.l.b(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
对象,这意味着我不重新创建它们,而是重用它们。我可以清楚地看到,每个
位图
对象都是从缓存中获取的,而不是从其他地方获取的。但是,如果
位图
尚未在缓存中(第一次加载),我将从我的应用程序的内部存储器加载它,但它仅在
位图
第一次加载时发生。我将
LruCache
的实例保存在保留的
片段
实例中,并在每次重新创建
活动
并且需要重新绘制映射时将其传递给我的自定义
DefaultClusterRenderer
对象

这是我的
DefaultClusterRenderer
扩展名:

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);
}
}
内存随着每次屏幕旋转而不断增加,当我旋转屏幕直到应用程序崩溃时,我越是放大地图(显示的标记越多),我的应用程序堆中添加的内存就越多

有时错误与上述不同,但显示OOM发生在my
DefaultClusterRenderer
extension
markerOptions.icon(BitmapDescriptorFactory.fromBitmap(位图))中的这一行


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

好的。。。我想这应该行得通

每当您想重置地图时,添加
googleMap.clear()


希望这能对您有所帮助。

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

我尝试了System gc(),分离片段、单例活动、将google play服务更新为最新版本、清除覆盖的引用、将地图生命周期附加到活动等等。 经过多次失败的尝试和挫折,我终于找到了一些有效的方法。这不是地图错误的修复程序,但它阻止了我的应用程序崩溃:

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


您在主要活动中尝试过这些吗@重写public void onLowMemory(){super.onLowMemory();mapView.onLowMemory();}我的意思是在活动或片段中,映射视图添加了…注释编辑。。检查一下……不,我没有,但我试过
System.gc()
。这没用。。。我想他们几乎是一样的。试试这个代码,让我知道结果。。。最好的……只是添加我的评论供将来的任何人查找-System.gc()似乎没有任何区别。查看Android Studio中的分析器,在调用gc()之前,“图形”占用198.1MB,在gc()之后占用198.2MB,所以没有区别。然而,调用map.clear()产生了巨大的不同。在map.clear()之前,“graphics”是198.1MB,而在clear()之后是73.1MB,这是一个很大的缩减。我们也尝试过这个。不走运。我甚至尝试将每个标记的图标分别设置为默认值,然后在
活动
onDestroy()
中逐个删除它们。我花了几个小时才碰到这个线程。我结合使用了三种答案:largeHeap、System.gc和map.clear。它起作用了android:largeHeap=“true”将有助于提高应用程序的内存使用率,但无助于解决您的问题。如果没有largeHeap,则意味着largeHeap为false,则您的应用程序可以运行30分钟。因此,如果largeHeap是真的,那么让你的应用程序持续更长的时间而不会崩溃,就像一个或两个小时…等等。正确,这就是为什么我说“这不是修复”。
    <application
    ...
    android:largeHeap="true">