objective-c - 您可以重复使用已清除的 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
。
所以看起来它们已成功清除,但内存仍分配给我的应用程序。为什么会这样?这些表面处于什么状态?
头文件指出我应该假设它们中有“未定义的内容”。很公平。
但是实际IOSurfaceRef
或IOSurface *
对象仍然有效吗?我可以成功查询它的所有属性,并且可以成功锁定它以进行读写。
即使它的内容已被清除,我是否可以只重用该对象,或者我是否必须丢弃该实例并创建一个全新的 IOSurface?
macOS 10.14
解决方案
是的,它仍然可以使用。只是像素数据丢失了。
基本上,当系统处于内存压力之下时,它通常会将数据分页到磁盘。将可清除对象标记为易失性允许系统简单地丢弃该数据。该应用程序表明,虽然它很值得拥有,但它不是必须拥有的,并且可以在必要时重新创建。
当它想IOSurface
再次使用时,应用程序应该将对象标记为非易失性并检查旧状态。如果它是空的,那么应用程序应该重新创建数据。
Instruments 报告您的应用程序仍然分配了 6GB 的原因是因为它为IOSurface
s 保留了 6GB 的地址空间。但已分配并不一定意味着由物理 RAM 或交换文件支持。在实际使用内存之前,它只是簿记。您的应用程序的驻留集大小 (RSS) 应该缩小。
推荐阅读
- google-cloud-transcoder - 来自规范配置的 WebM Spritesheet/转码在谷歌云中失败
- db2 - IBM Websphere Portal (IBM Content Manager) 中的表之间的关系在哪里?
- laravel - 如何在 Laravel 5.8 中获取以前的路线名称
- angular - Angular CLI:12.2.0“没有重载匹配这个调用。”
- ruby-on-rails - 在 Visual Studio Code 中运行或调试 Ruby 代码没有给我任何输出或消息
- node.js - 无法使用 greenlock-express 设置安全连接
- reactjs - Reactjs IF 语句
- python - 如何在英语和阿拉伯语的python中删除注释和减少拉长的单词?
- c++ - Qt 中的 SQL 数据库输出
- node.js - Sequelize 普通对象返回空 - 花括号行为不端