内存映射文件和低内存场景

发布于 2024-11-10 13:30:31 字数 539 浏览 7 评论 0原文

iOS平台在低内存场景下如何处理内存映射文件?低内存场景是指当操作系统向应用程序中的所有观察者发送 UIApplicationDidReceiveMemoryWarningNotification 通知时。

我们的文件使用 +[NSData dataWithContentsOfMappedFile:],其文档指出:

映射文件使用虚拟内存技术来避免将文件页面复制到内存中,直到实际需要它们为止。

这是否意味着操作系统也会在不再使用页面时取消映射这些页面?是否可以将页面标记为不再使用?如果情况发生变化,该数据是只读的。如果我们直接使用 mmap() 怎么样?这会更好吗?

How does the iOS platform handle memory-mapped files during low-memory scenarios? By low-memory scenarios, I mean when the OS sends the UIApplicationDidReceiveMemoryWarningNotification notification to all observers in the application.

Our files are mapped into memory using +[NSData dataWithContentsOfMappedFile:], the documentation for which states:

A mapped file uses virtual memory techniques to avoid copying pages of the file into memory until they are actually needed.

Does this mean that the OS will also unmap the pages when they're no longer in use? Is it possible to mark pages as being no longer in use? This data is read-only, if that changes the scenario. How about if we were to use mmap() directly? Would this be preferable?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

錯遇了你 2024-11-17 13:30:31

内存映射文件将数据从磁盘复制到内存中,每次一页。与任何其他虚拟内存一样,未使用的页面可以自由换出,除非它们已使用 mlock(2) 连接到物理内存。内存映射决定了将哪些内容从磁盘复制到内存以及何时复制到操作系统。

从 Foundation 级别降到 BSD 级别来使用 mmap 不太可能产生太大影响,除了使必须与其他 Foundation 代码交互的代码变得更加尴尬之外。

Memory-mapped files copy data from disk into memory a page at a time. Unused pages are free to be swapped out, the same as any other virtual memory, unless they have been wired into physical memory using mlock(2). Memory mapping leaves the determination of what to copy from disk to memory and when to the OS.

Dropping from the Foundation level to the BSD level to use mmap is unlikely to make much difference, beyond making code that has to interface with other Foundation code somewhat more awkward.

风追烟花雨 2024-11-17 13:30:31

(这不是答案,但会是有用的信息。)

来自 @ID_AA_Carmack 推文,

@ID_AA_Carmack iOS 内存映射文件在内存不足的情况下会自动取消映射吗? (使用+[NSData dataWithContentsOfMappedFile]?)

ID_AA_Carmack对此回复,

@KhrobEdmonds 是的,这是在 iOS 上使用映射文件的巨大好处之一。不过,我使用 mmap()。

我不确定这是真的还是假的...

(This is not an answer, but it would be useful information.)

From @ID_AA_Carmack tweet,

@ID_AA_Carmack are iOS memory mapped files automatically unmapped in low memory conditions? (using +[NSData dataWithContentsOfMappedFile]?)

ID_AA_Carmack replied for this,

@KhrobEdmonds yes, that is one of the great benefits of using mapped files on iOS. I use mmap(), though.

I'm not sure that is true or not...

三生殊途 2024-11-17 13:30:31

根据我的实验, NSData 不会响应内存警告。我通过创建内存映射 NSData 并访问文件的部分内容进行测试,以便将其加载到内存中,最后发送内存警告。内存警告后内存使用量没有减少。文档中没有任何内容表明内存会导致 NSData 在内存不足的情况下减少实际内存使用量,因此它让我相信它不会响应内存警告。例如,NSCache 文档说它会尝试在内存使用方面发挥良好作用,而且我被告知它会响应系统发出的低内存警告。

另外,在 iPod Touch(第 4 代)上的简单测试中,我能够使用 +[NSData dataWithContentsOfMappedFile:] 将大约 600 兆的文件数据映射到虚拟内存中。接下来,我开始通过 NSData 实例上的 bytes 属性访问页面。当我这样做时,实际内存开始增长,但在实际内存使用量约为 30 兆时停止增长。因此,它的实现方式似乎限制了将使用多少实际内存。

简而言之,如果您想减少 NSData 对象的内存使用量,最好的选择是实际确保它们完全释放,而不是依赖于系统自动代表您执行的任何操作。

From my experiments NSData does not respond to memory warnings. I tested by creating a memory mapped NSData and accessing parts of the file so that it would be loaded into memory and finally sending memory warnings. There was no decrease in memory usage after the memory warning. Nothing in the documentation says that a memory will cause NSData to reduce real memory usage in low memory situations so it leads me to believe that it does not respond to memory warnings. For example NSCache documentation says that it will try and play nice with respect to memory usage plus I have been told it responds to the low memory warnings the system raises.

Also in my simple tests on an iPod Touch (4th gen) I was able to map about 600 megs of file data into virtual memory use +[NSData dataWithContentsOfMappedFile:]. Next I started to access pages via the bytes property on the NSData instance. As I did this real memory started to grow however it stopped growing at around 30 megs of real memory usage. So the way it is implemented it seems to cap how much real memory will be used.

In short if you want to reduce memory usage of NSData objects the best bet is to actually make sure they are completely released and not relying on anything the system automagically does on your behalf.

删除→记忆 2024-11-17 13:30:31

如果 iOS 与任何其他 Unix 一样——我敢打赌,在这方面确实如此——mmap() 区域中的页面不会被“交换出”;它们只是被删除(如果它们是干净的)或被写入底层文件然后被删除(如果它们是脏的)。此过程称为“驱逐”页面。

由于您的内存映射是只读的,因此页面将始终是干净的。

当物理内存紧张时,内核将决定驱逐哪些页面。

您可以使用 posix_madvise()。特别是,POSIX_MADV_DONTNEED 告诉内核可以随意驱逐页面;或者正如您所说,“将页面标记为不再使用”。

编写一些测试程序来查看 iOS 是否遵循“不需要”提示应该非常简单。既然它是从 BSD 派生的,我打赌它会的。

If iOS is like any other Unix -- and I would bet money it is in this regard -- pages in an mmap() region are not "swapped out"; they are simply dropped (if they are clean) or are written to the underlying file and then dropped (if they are dirty). This process is called "evicting" the page.

Since your memory map is read-only, the pages will always be clean.

The kernel will decide which pages to evict when physical memory gets tight.

You can give the kernel hints about which pages you would prefer it keep/evict using posix_madvise(). In particular, POSIX_MADV_DONTNEED tells the kernel to feel free to evict the pages; or as you say, "mark pages as being no longer in use".

It should be pretty simple to write some test programs to see whether iOS honors the "don't need" hint. Since it is derived from BSD, I bet it will.

帥小哥 2024-11-17 13:30:31

文件支持内存的标准虚拟内存技术表明,操作系统可以随时丢弃页面,因为它以后总是可以再次获取它们。我没有使用过 iOS,但这长期以来一直是许多其他操作系统上虚拟内存的行为。

测试它的最简单方法是将几个大文件映射到内存中,通读它们以确保将它们分页到内存中,然后看看是否可以强制出现内存不足的情况。如果不能,那么操作系统在确定不再使用这些页面后必须取消映射这些页面。

Standard virtual memory techniques for file-backed memory says that the OS is free to throw away pages whenever it wants because it can always get them again later. I have not used iOS, but this has been the behavior of virtual memory on many other operating systems for a long time.

The simplest way to test it is to map several large files into memory, read through them to guarantee that it pages them into memory, and see if you can force a low memory situation. If you can't, then the OS must have unmapped the pages once it decided that they were no longer in use.

三人与歌 2024-11-17 13:30:31

dataWithContentsOfMappedFile: 方法现已从 iOS5 中弃用。

使用 mmap,因为您将避免这些情况。

The dataWithContentsOfMappedFile: method is now deprecated from iOS5.

Use mmap, as you will avoid these situations.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文