GMSPolyline内存峰值非常大

时间:2013-03-15 21:19:11

标签: optimization memory-management gps google-maps-sdk-ios

在GPS应用程序中,用户可以显示我们在各种不同类型的地图上调用轨道的复杂位置点列表,每个轨道可以包含2k到10k的位置点。当在非Google地图类型上渲染轨道时,轨道会被大量剪裁,修剪和路径简化。这是为了降低内存使用率并提高性能。我们通常最终只会向OpenGL管道提交远远少于一千(聚合)转换的位置点,即使在最坏的情况下也是如此。

在整合Google Maps SDK for iOS时,我们最初尝试继续利用我们自己的OpenGL轨道渲染系统,但遇到了与OpenGL上下文冲突相关的问题(渲染工作正常,但我们无法获得GMSMapView和我们自己的内部OpenGL资源,无需人员触摸已删除的内存即可释放)。

因此,我们正在尝试利用GMSPolyline构造并让Google SDK执行轨道渲染,但我们遇到了主要的内存使用问题,并正在寻找解决它们的指导。

使用Xcode Instruments,我们在创建约25条多线路时监控内存使用情况,总线位置总数约为23k(不是每个)。在创建多线路的过程中,应用内存使用量从大约14 MB增加到大约172 MB,净峰值大约为158 MB。在创建所有多边形线之后不久,内存使用率最终下降到大约19 MB并且看起来稳定,累积净值大约为5 MB,所以看起来每个位置点需要大约220个字节(5 MB / 23k点)到存储。

伤害我们的是最大内存使用量。虽然我们的实验室测试仅使用了23k个位置点,但在现实世界中通常会有更多,而iOS似乎在 Google Maps iPhone 5上消耗了大约450 MB后放弃了我们的应用程序/ em>(而我们的内部多线渲染系统在同一测试用例中的峰值大约为12 MB)。

显然,GMSPolyLine构造不适用于我们需要的大量使用。

我们尝试使用单独的自动释放池包装一些多边形线创建循环,然后在适当的位置排出这些循环,但这对内存使用没有影响。在创建多边形线并且控制返回到主运行循环之后的峰值内存使用根本没有改变。后来很明显为什么;在创建多边形线之后,第一个DisplayLink回调之前,Google Map系统不会释放资源。

我们接下来的努力将是手动限制我们在GMSPolyline上推送的数据量,可能使用我们自己的边界测试,裁剪,修剪和放大。最小化,而不是依靠谷歌地图有效地做到这一点。

这里的缺点是,当用户在地图上平移/缩放时,可能会分配和释放更多GMSPolyline对象。这些对象中的每一个都将具有更少的位置点,但是,我们仍然担心这种方法的无法预料的后果,许多GMSPolyline分配和解除分配的隐藏开销。

所以问题是,处理这种情况的最佳方法是什么,谷歌的某些人是否可以对任何GMSPolyline最佳做法,上限,瓶颈等有所了解?

1 个答案:

答案 0 :(得分:1)

为什么不根据基本的http请求尝试使用google API进行指导。 https://developers.google.com/maps/documentation/directions/。 (检查许可条件和请求的条件)。

然后使用IOS MKPolyline绘制数据。我肯定你会有更好的表现。而且你只会依靠谷歌的定位数据。

将谷歌API的响应转换为坐标,使用下面众所周知的方法(取自其他帖子):

- (NSMutableArray *)parseResponse:(NSDictionary *)response
{
    NSArray *routes = [response objectForKey:@"routes"];
    NSDictionary *route = [routes lastObject];
    if (route) {
        NSString *overviewPolyline = [[route objectForKey: @"overview_polyline"] objectForKey:@"points"];
        return  [self decodePolyLine:overviewPolyline];
    }
    return nil;
}


-(NSMutableArray *)decodePolyLine:(NSString *)encodedStr {

    NSMutableString *encoded = [[NSMutableString alloc]initWithCapacity:[encodedStr length]];
    [encoded appendString:encodedStr];
    [encoded replaceOccurrencesOfString:@"\\\\" withString:@"\\"
                                options:NSLiteralSearch range:NSMakeRange(0,
                                                                          [encoded length])];
    NSInteger len = [encoded length];
    NSInteger index = 0;
    NSMutableArray *array = [[NSMutableArray alloc] init]; NSInteger lat=0;
    NSInteger lng=0;
    while (index < len) {
        NSInteger b; NSInteger shift = 0; NSInteger result = 0; do {
            b = [encoded characterAtIndex:index++] - 63; result |= (b & 0x1f) << shift;
            shift += 5;
        } while (b >= 0x20);
        NSInteger dlat = ((result & 1) ? ~(result >> 1)
                          : (result >> 1)); lat += dlat;
        shift = 0; result = 0; do {
            b = [encoded characterAtIndex:index++] - 63; result |= (b & 0x1f) << shift;
            shift += 5;
        } while (b >= 0x20);
        NSInteger dlng = ((result & 1) ? ~(result >> 1)
                          : (result >> 1)); lng += dlng;
        NSNumber *latitude = [[NSNumber alloc] initWithFloat:lat * 1e-5]; NSNumber *longitude = [[NSNumber alloc] initWithFloat:lng * 1e-5];
        CLLocation *location = [[CLLocation alloc] initWithLatitude: [latitude floatValue] longitude:[longitude floatValue]];
        [array addObject:location]; }
    return array;
}

我在google sdk上有类似的性能问题,它对我有用。