GMSPolyline 非常大的内存峰值 [英] GMSPolyline very large memory spike

查看:21
本文介绍了GMSPolyline 非常大的内存峰值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In a GPS app that allows the user to display a list of complex location points that we call tracks on various different types of map, each track can consist of between 2k to 10k of location points. The tracks are copiously clipped, pruned and path-simplified when they are rendered on non-Google map types. This is to keep memory usage down and performance up. We typically only wind up submitting far less than a thousand (aggregate) transformed location points to the OpenGL pipeline, even in the worst cases.

在集成适用于 iOS 的 Google Maps SDK 时,我们最初尝试继续利用我们自己的 OpenGL 轨迹渲染系统,但遇到了 OpenGL 上下文使用冲突的问题(渲染工作正常,但我们无法使用 GMSMapView 和我们自己的内部 OpenGL 资源都可以在没有人接触已删除内存的情况下释放).

In integrating the Google Maps SDK for iOS, we initially attempted to continue to leverage our own OpenGL track rendering system, but ran into issues with conflicting OpenGL context usage (rendering worked, but we couldn't get GMSMapView to and our own internal OpenGL resources to both release without someone touching deleted memory).

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

So we are trying to leverage the GMSPolyline constructs and just let the Google SDK do the track rendering, but we've run into major memory usage issues, and are looking for guidance in working around them.

使用 Xcode Instruments,我们在创建大约 25 条折线时监控了内存使用情况,总共有大约 23k 个位置点(不是每条).在折线创建过程中,应用程序内存使用量从大约 14 MB 增长到大约 172 MB,净峰值约为 158 MB.在创建所有折线后不久,内存使用量最终回落到 19 MB 左右并且看起来很稳定,累积净值约为 5 MB,因此每个位置点似乎需要大约 220 字节(5 MB/23k 点)来商店.

Using Xcode Instruments, we've monitored memory usage when creating about 25 poly lines with about 23k location points total (not each). Over the course of poly line creation, app memory usage grows from about 14 MB to about 172 MB, a net peak of about 158 MB. Shortly after all the poly lines are created, memory usage finally drops back down to around 19 MB and seems stable, for a cumulative net of around 5 MB, so it seems each location point requires around 220 bytes (5 MB / 23k points) to store.

让我们感到痛苦的是内存使用高峰.虽然我们的实验室测试只使用了 23k 位置点,但在现实世界中通常还有更多,而且 iOS 似乎在 Google 地图 在 iPhone 5 上消耗了大约 450 MB 之后放弃了我们的应用程序/em>(而对于相同的测试用例,我们的内部折线渲染系统的峰值约为 12 MB).

What hurts us is the peak memory usage. While our laboratory test only used 23k location points, in the real world there are often many more, and iOS seems to jettison our application after Google Maps has consumed around 450 MB on an iPhone 5 (whereas our internal poly line rendering system peaks at around 12 MB for the same test case).

显然,GMSPolyLine 构造不适用于我们需要的重量级用法.

Clearly the GMSPolyLine construct is not intended for the heavy weight usage that we require.

我们尝试使用单独的自动释放池包装一些折线创建循环,然后在适当的点排空这些循环,但这对内存使用没有影响.创建多段线并将控制权返回到主运行循环后的峰值内存使用根本没有改变.后来很清楚为什么;在创建折线后的第一个 DisplayLink 回调之前,Google 地图系统不会释放资源.

We tried wrapping some of the poly line creation loops with separate autorelease pools, and then draining those at appropriate points, but this has no impact on memory use. The peak memory use after the poly lines are created and control is returned to the main run loop didn't change at all. Later it became clear why; the Google Map system isn't releasing resources until the first DisplayLink callback after the poly lines are created.

我们的下一步工作将是手动限制我们在 GMSPolyline 推送的数据量,可能会使用我们自己的边界测试、裁剪、修剪和最小化,而不是依靠谷歌地图来有效地做到这一点.

Our next effort will be to manually throttle the amount of data we're pushing at GMSPolyline, probably using our own bounds testing, clipping, pruning & minimization, rather than relying on Google Maps to do this efficiently.

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

The drawback here is that it will mean many more GMSPolyline objects will be allocated and deallocated, potentially while the user is panning/zooming around the map. Each of these objects will have far fewer location points, yet still, we're concerned about unforeseen consequences of this approach, hidden overhead of many GMSPolyline allocs and deallocate.

所以问题是,处理这种情况的最佳方法是什么,Google 的某个人能否阐明任何 GMSPolyline 最佳实践、上限、瓶颈等?

So the question is, what is the best approach for dealing with this situation, and can someone from Google shed some light on any GMSPolyline best practices, upper bounds, bottlenecks, etc. ?

推荐答案

你为什么不尝试使用google API来指导,基于基本的http请求.https://developers.google.com/maps/documentation/directions/ .(检查许可条件和请求数量).

why don´t you try to use google API for direction, based on basic http requests. https://developers.google.com/maps/documentation/directions/ . (check the conditions on licensing and nº of requests).

然后用 IOS MKPolyline 绘制数据.我相信你会有更好的表现.而且您将只依靠谷歌来获取定位数据.

And then plot the the data with IOS MKPolyline. i´m Sure you will have better performance. And you will only depend on google for the positioning data.

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

to convert the response from google API to coordinates, use the well known method (taken from other post) below:

- (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 上遇到了类似的性能问题,它对我有用.

I had a similar problem with performance on google sdk and it work for me.

这篇关于GMSPolyline 非常大的内存峰值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆