【问题标题】:Can you reuse an IOSurface that has been purged?您可以重复使用已清除的 IOSurface 吗?
【发布时间】:2019-02-06 18:41:57
【问题描述】:

TL;DR:IOSurfaceRef 在被清除且状态更改为 kIOSurfacePurgeableEmpty 后是否是可写入的有效表面?


我正在尝试更好地了解清除 IOSurface 意味着什么。我遇到的唯一文档是IOSurfaceRef.h,我遇到的唯一示例代码是WebKit。

我正在使用命令行工具memory_pressure 来模拟 10 秒的关键内存压力环境,如下所示:

> memory_pressure -S -s 10 -l critical

我编写了一个非常简单的应用程序,它分配了 100 个具有相同属性的 IOSurfaces。当我使用 Instruments 测量内存分配时,我看到 VM: IOSurface 大约为 6GB,每个表面大约为 6MB。 (4096x4096x4)

然后我将每个 IOSurface 的可清除状态更改为 kIOSurfacePurgeableVolatile 并运行 memory_pressure 模拟。

仪器仍然报告我分配了 6GB 的表面。但是,如果我检查每个表面的可清除状态,它们会被标记为kIOSurfacePurgeableEmpty。

看起来它们已成功清除,但内存仍分配给我的应用程序。为什么会这样?这些表面处于什么状态?

头文件声明我应该假设它们中有“未定义的内容”。很公平。

但是实际的IOSurfaceRef 或IOSurface * 对象仍然有效吗?我可以成功查询它的所有属性,并且可以成功锁定它以进行读写。

我是否允许仅重用该对象,即使其内容已被清除,还是我必须丢弃该实例并创建一个全新的 IOSurface?

macos 10.14

【问题讨论】:

    标签: objective-c macos memory-management core-foundation iosurface


    【解决方案1】:

    是的,它仍然可以使用。只是像素数据丢失了。

    基本上,当系统处于内存压力之下时,它通常会将数据分页到磁盘。将可清除对象标记为易失性允许系统简单地丢弃该数据。该应用程序表明,虽然它很值得拥有,但它不是必须拥有的,并且可以在必要时重新创建。

    当它想再次使用IOSurface 时,应用程序应该将对象标记为非易失性并检查旧状态。如果它是空的,那么应用程序应该重新创建数据。

    Instruments 报告您的应用仍分配有 6GB 的原因是因为它为IOSurfaces 保留了 6GB 的地址空间。但已分配并不一定意味着由物理 RAM 或交换文件支持。在实际使用内存之前,它只是簿记。您的应用的驻留集大小 (RSS) 应该会缩小。

    【讨论】:

    • 这就是我的结论,但有一件事我仍然不明白。如果系统处于真正的内存压力下并且我的表面被清除了,那么可能是其他一些进程“占用”了该内存供自己使用。如果我然后通过将我的表面标记为非易失性来请求它“返回”,那么如果系统无法回收内存会发生什么?我没有看到任何 IOSurface API 表明无法重新分配已清除的表面,所以我一定不明白。虚拟机是否只是将其他所有内容分页到磁盘,直到我“恢复”我的 6GB?
    • 基本上,是的。这是虚拟内存的一般行为。在使用 VM 的极端情况下,您可以获得thrashing。在现代操作系统上,分配永远不会因为内存不足而失败,只是因为地址空间不足。而且,对于 64 位进程,这也几乎不会发生。对于这种IOSurface 的情况,无论如何,地址空间已经分配好了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多