您可以重复使用已清除的 IOSurface 吗?

Can you reuse an IOSurface that has been purged?

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.

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

头文件声明我应该假定它们中有 "undefined content"。很公平。

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

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

macOS 10.14

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

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

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

Instruments 报告您的应用仍分配了 6GB 的原因是因为它有 6GB 地址 space 保留给 IOSurface。但分配并不一定意味着由物理 RAM 或交换文件支持。它只是记账,直到内存被实际使用。您的应用程序的常驻集大小 (RSS) 应该缩小。