Optimization GMSPolyline非常大的内存尖峰

Optimization GMSPolyline非常大的内存尖峰,optimization,memory-management,gps,google-maps-sdk-ios,Optimization,Memory Management,Gps,Google Maps Sdk Ios,在一个GPS应用程序中,用户可以显示一系列复杂的位置点,我们称之为各种不同类型地图上的轨迹,每个轨迹可以包含2k到10k的位置点。在非谷歌地图类型上渲染轨迹时,轨迹会被大量剪裁、修剪和路径简化。这是为了降低内存使用率,提高性能。即使在最坏的情况下,我们通常只向OpenGL管道提交远远少于一千个(合计)转换的位置点 在集成Google Maps SDK for iOS时,我们最初试图继续利用我们自己的OpenGL轨迹渲染系统,但遇到了OpenGL上下文使用冲突的问题(渲染工作正常,但我们无法在没有

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

在集成Google Maps SDK for iOS时,我们最初试图继续利用我们自己的OpenGL轨迹渲染系统,但遇到了OpenGL上下文使用冲突的问题(渲染工作正常,但我们无法在没有人触摸已删除内存的情况下将GMSMapView和我们自己的内部OpenGL资源同时发布)

因此,我们试图利用GMSPolyline构造,只让googlesdk进行轨迹渲染,但我们遇到了主要的内存使用问题,正在寻找解决这些问题的指导

使用Xcode工具,我们在创建总共约23k个位置点(不是每个位置点)的25条多边形线时监控了内存使用情况。在poly line创建过程中,应用程序内存使用量从约14MB增加到约172MB,净峰值约为158MB。在创建了所有多边形线之后不久,内存使用量最终下降到19MB左右,并且看起来比较稳定,因为累计净容量约为5MB,因此每个位置点似乎需要大约220字节(5MB/23k点)来存储

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

显然,
GMSPolyLine
结构不适用于我们要求的重型用途

我们尝试用单独的自动释放池包装一些多边形线创建循环,然后在适当的点上排空这些循环,但这对内存使用没有影响。创建多边形线并将控制返回到主运行循环后的峰值内存使用根本没有改变。后来,原因变得很清楚;谷歌地图系统在创建多边形线条后的第一次DisplayLink回调之前不会释放资源

我们下一步的工作将是手动控制我们在GMSPolyline上推送的数据量,可能使用我们自己的边界测试、剪裁、修剪和最小化,而不是依靠谷歌地图来高效地完成

这里的缺点是,这将意味着更多的GMSPolyline对象将被分配和解除分配,而用户可能在地图周围平移/缩放。这些对象中的每一个都将有更少的定位点,但我们仍然担心这种方法的不可预见的后果,许多GMSPolyline alloc和deallocate的隐藏开销


因此,问题是,处理这种情况的最佳方法是什么,谷歌的某个人能否解释一下任何
GMSPolyline
最佳实践、上限、瓶颈等?

基于基本http请求,为什么不尝试使用谷歌API进行指导。(检查许可条件和请求编号)

然后用IOS MKPolyline绘制数据。我相信你会有更好的表现。你将只依赖谷歌的定位数据

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

-(NSMutableArray*)解析响应:(NSDictionary*)响应
{
NSArray*routes=[response objectForKey:@“routes”];
NSDictionary*route=[routes lastObject];
如果(路线){
NSString*概览多段线=[[route objectForKey:@“overview_polyline”]objectForKey:@“points”];
返回[自解码多段线:概览多段线];
}
返回零;
}
-(NSMutableArray*)解码多段线:(NSString*)编码器{
NSMutableString*encoded=[[NSMutableString alloc]initWithCapacity:[EncodedStrength]];
[encoded appendString:encodedStr];
[encoded ReplaceAccurrencesofString:@“\\\\”和字符串:@“\\”
选项:NSLiteralSearch范围:NSMakerRange(0,
[编码长度];
NSInteger len=[编码长度];
NSInteger指数=0;
NSMUTABLEARRY*array=[[NSMUTABLEARRY alloc]init];NSInteger lat=0;
NSInteger液化天然气=0;
while(指数>1)
:(结果>>1));lat+=dlat;
移位=0;结果=0;执行{
b=[encoded characterAtIndex:index++]-63;结果|=(b&0x1f)=0x20);
NSInteger dlng=((结果&1)~(结果>>1)
:(结果>>1));lng+=dlng;
NSNumber*纬度=[[NSNumber alloc]initWithFloat:lat*1e-5];NSNumber*经度=[[NSNumber alloc]initWithFloat:lng*1e-5];
CLLocation*location=[[CLLocation alloc]initWithLatitude:[纬度浮点值]经度:[经度浮点值]];
[数组addObject:位置];}
返回数组;
}

我在google sdk上遇到了类似的性能问题,它对我很有效。

团队将对此进行调查。我会在为您提供更新时做出响应。FWIW我们尝试限制我们的GMSPolyLine提交,甚至将每条多边形线预修剪到1000点以下。启用限制后,我们将每隔50毫秒提交每条多边形线(也尝试了其他间隔)但是记忆
- (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;
}