gpt4 book ai didi

ios - iOS的虚拟内存限制是多少?

转载 作者:行者123 更新时间:2023-12-01 20:26:59 61 4
gpt4 key购买 nike

iOS的虚拟内存体使用量有上限吗?确定必须存在,但无法对其进行追踪。

最佳答案

tl; dr:

操作系统没有直接或明确的虚拟内存限制,因此理论上您的应用程序可以分配其整个潜在的逻辑地址空间。对于32位处理器,此大小为4 GB,对于64位处理器,此大小为18 exa。

实际上,可用虚拟内存大小存在局限性,这在很大程度上取决于应用程序如何使用其内存空间。这些限制源自操作系统管理虚拟内存的方式效率低下,因为针对低功耗(而不是繁重的文件I/O)进行了积极的操作系统调整。

如果您不在乎这些实际限制的详细信息,请随时在此处停止阅读。否则,以下是我在研究iOS上的内存问题以及虚拟内存和内存映射文件的入门方面的笔记,以及关于iOS与其他OS的不同之处的大量讨论。

什么是虚拟内存?

在包括iOS在内的现代操作系统中,您的进程可以访问的所有内存在技术上都是虚拟内存。之所以称为“虚拟”内存,是因为暴露给进程的地址空间(称为进程的逻辑地址空间)不一定与计算机的物理地址空间甚至其他进程的虚拟地址空间一致。虚拟内存允许内核在不同的上下文中提供不同的逻辑地址空间。

在iOS上,此逻辑地址空间的大小理论上仅受指针大小限制,该指针大小由处理器体系结构定义。这意味着进程在32位处理器上大约具有4 GB的逻辑存储空间,而在64位处理器上则具有18 EB的逻辑存储空间。

但是我的设备只有2GiB的RAM,如何实际使用18艾字节的存储空间?

要回答这个问题,首先您必须认识到,当您的进程调用诸如malloc之类的东西来获取一些内存时,内核会在进程的逻辑地址空间中设置一小部分,并将其标记为已分配。在这种情况下,此分配的内存也占用物理内存空间。存储在物理内存中的数据称为驻留,因为它驻留在物理内存中,而驻留的数据被称为驻留集的一部分。内核通常通过跟踪进程的常驻集大小来将您的物理内存使用量与物理内存限制进行比较。

如果这是您的进程分配内存的唯一方法,那么对于大多数现代操作系统,您的进程将受到未分配物理内存量,机器页面文件,交换分区或其他一些可用空间的限制。非 volatile 后备存储。但是,iOS没有后备存储,它会强制执行strict constraints on the maximum resident set size of a process,因此通常,应用程序的常驻集大小将受到可用物理内存和每个进程常驻集限制中较小者的限制。

因此,如果分配内存永远都无法让您达到极限,那么为什么还要烦恼每个进程拥有18 EB的地址空间呢?

内存映射文件就是一个有用的例子。

当您有一个需要快速访问文件的应用程序并且想要依靠内核来确定要读取文件的哪些位以及何时读取时,可以对文件进行内存映射(请参阅 mmap 的文档)。在这种情况下,内核将文件(或您请求的文件的一部分)作为进程逻辑地址空间的连续区域呈现给您的进程。

内存映射文件如何工作?

操作系统将限制访问逻辑内存空间中为映射文件保留的部分,并在访问文件时将文件的大块透明地复制到物理内存中。这些“块”称为页面,而允许内核执行此操作的陷阱称为page fault,而使数据驻留的行为称为分页输入,而从内存中删除页面的操作称为分页输出。所有这些使您的过程看起来就像您一直在内存中拥有已映射文件的区域(或整个文件,如果您要映射的是整个文件)。当然,为了使其正常工作,操作系统必须检测一段时间未访问的页面并将其分页出来。

iOS映射文件支持与其他操作系统有何不同?

在上述情况下,与大多数 table 面类操作系统相比,iOS有所限制。具体来说,从我在文档中看到的内容来看,似乎iOS上的页面只有使用PROT_READ标志以只读方式映射时,才能从物理内存中清除。这意味着,如果您使用PROT_WRITE标志映射文件,则该文件中的页面将保持驻留状态,直到您调用munmap(我无法单独从文档中得知这是否意味着所有页面都将保持驻留状态,或者仅仅是修改后的页面,停在附近)。

此行为有别于其他操作系统,例如在PROT_WRITEMAP_SHARED的情况下,可以随时清除未修改的页面,并且一旦它们与磁盘同步(即一旦它们不再“脏”),就可以清除未修改的页面。 )。同样在其他操作系统上,当使用PROT_WRITEMAP_PRIVATE时,未修改页面的情况保持不变,但是只要OS使用某种“后备存储”(例如页面文件),仍可以从物理内存中清除已修改页面。

在后一种情况下,iOS无法分页这些修改,因为它没有后备存储。但是,我发现前一种情况令人困惑,因为从理论上讲,没有逻辑限制允许同步页面被调出。我最多可以推断的是,在PROT_WRITEMAP_SHARED的情况下,这些页面将保持驻留状态,以避免在SMP环境中I/O调度程序和寻呼机之间的紧密同步。文档(下面的链接)中的一个较弱的建议支持这种推论,即在OSX上,无论页面是否与磁盘同步,修改后的页面都将被写入后备存储。但是,我打算对Mach内核进行更多阅读,以更全面地理解这些限制。

所以mmapPROT_READ似乎是我们使用进程的所有可用VM空间而不达到常驻集大小限制的路径,对吗?我的意思是,理论上讲,使用这种方法,您可以多次创建一些大文件的只读映射,每个映射都占用您进程的可用逻辑内存空间的单独部分。在32位操作系统上,甚至在32位iOS上,您也可以很容易地通过虚拟地址空间饱和来实现您对世界支配的周密计划。大家的ENOMEM!

因此,如果没有任何虚拟内存限制,为什么在我映射只读文件时我的应用程序被杀死?

实际上,虽然在许多操作系统上,您都可以mmap一个文件,并且在OS知道细节的情况下放轻松,但在iOS上并非如此。即使只读映射文件在进程的逻辑地址空间中占主导地位,您的应用程序仍然有可能因为超过常驻设置的内存限制而被杀死。发生这种情况是因为内核决定了可以从物理内存中删除哪些页面的方式。

阅读下一部分时,请记住,iOS的电源效率已进行了非常积极的调整。它不是文件服务器。

内核只会释放已标记为不 Activity 的页面,我将从下面链接的文档中推断出,只有在某个阈值时间段内未触摸过的页面才能将页面标记为不 Activity 。

我还将根据文档和我自己的经验推断,负责标记页面处于非 Activity 状态的内核部分与负责检查驻留集大小限制的内核部分无法很好地协调。

当您的驻留集大小接近极限时,操作系统会尝试清除不 Activity 的页面,并发出内存警告,期望您的应用通过减小驻留集大小来对此做出响应。一旦您的居民集大小超过某个阈值,Jetsam就会杀死您的应用程序。

因此,鉴于上述情况,当您的应用程序对大量页面进行大量随机访问时,如果负责标记页面处于非 Activity 状态的内核部分没有运行一段时间,会发生什么情况?

即使您的大部分驻留集被只读映射文件的页面占用,您的应用也会被杀死。

我认为这是苹果建议尽可能使用更小,更瞬时的映射而不是映射整个文件的主要原因之一(尽管在这种使用模式下,内存空间碎片开始成为人们关注的问题)。

这个答案还不够长!我需要更多信息!

如果您想了解更多信息,请参阅virtual memory in iOS and OSX上的Apple文档以及memory mapped files section of the File System Advanced Programming Topics doc mmap man page for iOS

顺便说一句,还有一些其他相关主题值得阅读,这些主题使所有这些变得更加复杂和有用,例如页面锁定,页面同步,I/O缓存,预取,以及令人深为好奇的操作系统的运行方式。完成对共享映射的高效多处理访问。

关于ios - iOS的虚拟内存限制是多少?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32664679/

61 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com