【发布时间】:2012-04-14 11:47:02
【问题描述】:
我正在开发一个在上传前拆分文件的上传应用程序。它拆分文件以防止因使用过多内存而被 iOS 关闭,因为某些文件可能相当大。如果我可以设置最大内存使用量并使用它来确定大小,而不是设置最大“块”大小,那就太好了。
类似的东西
#define MAX_MEM_USAGE 20000000 //20MB
#define MIN_CHUNK_SIZE 5000 //5KB
-(void)uploadAsset:(ALAsset*)asset
{
long totalBytesRead = 0;
ALAssetRepresentation *representation = [asset defaultRepresentation];
while(totalBytesRead < [representation size])
{
long chunkSize = MAX_MEM_USAGE - [self getCurrentMemUsage];
chunkSize = min([representation size] - totalBytesRead,max(chunkSize,MIN_CHUNK_SIZE));//if I can't get 5KB without getting killed then I'm going to get killed
uint8_t *buffer = malloc(chunkSize);
//read file chunk in here, adding the result to totalBytesRead
//upload chunk here
}
}
基本上就是我想要的。我似乎无法找到一种方法来专门获取我的应用程序的当前内存使用情况。我并不关心剩余的系统内存量。
我能想到的唯一方法是我不太喜欢的方法。在我的应用程序的第一行获取系统内存量,然后将其存储在全局类中的静态变量中,然后 getCurrentMemUsage 会像这样
-(long)getCurrentMemUsage
{
long sysUsage = [self getSystemMemoryUsed];
return sysUsage - [Globals origSysUsage];
}
这有一些严重的缺点。对我来说最明显的是另一个应用程序可能会在我的上传过程中被杀死,这可能会使 sysUsage 低于 origSysUsage 从而导致负数,即使我的应用程序使用 10MB 内存,这可能导致我的应用程序使用 40MB一个请求,而不是 20MB 的最大值。我总是可以设置它,以便将值限制在 MIN_CHUNK_SIZE 和 MAX_MEM_USAGE 之间,但这只是一种解决方法,而不是实际的解决方案。
如果有任何关于获取应用程序使用的内存量或管理动态块大小的不同方法的建议,我将不胜感激。
【问题讨论】:
-
我只会使用 256KB 的块并完成它。拥有比这更大的块有什么显着优势吗?
-
@DavidSchwartz 只是它显着加快了上传过程。用户可能正在上传超过 1gb 的文件,因此上传它需要大量的块。 20MB 会占用很多块,但仍优于 256KB(或其他更小的值)。此外,有些文件不需要完整的 20MB 内存即可上传(例如 jpeg)。我们对这个应用程序的目标是能够以尽可能少的请求尽可能快地上传,而不会耗尽内存。
-
至少它加快了 android 上的上传过程,我敢肯定它在 iOS 设备上也是如此
-
我会尝试弄清楚为什么您的应用程序需要如此大的缓冲区来达到最佳性能并修复它,而不是试图解决这个缺陷。
-
我要上传到的服务器需要文件部分的顺序,所以我必须等待服务器给我一个响应,说它已经为下一部分做好了准备,然后我才能上传它。我实际上没有测试过任何大于 2MB 缓冲区和 20MB 文件的东西,但是我的请求越少,上传完成的速度就越快。在我进行文件拆分之前,20MB 的文件会非常快速地上传(因为它通过 LAN,几乎是立即上传),这就是我选择 20MB 作为理想内存使用级别的原因。