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

时间:2019-02-06 18:41:57

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

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模拟。

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

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

头文件指出我应该假定它们中包含“未定义的内容”。足够公平。

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

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

macos 10.14

1 个答案:

答案 0 :(得分:2)

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

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

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

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