malloc:由于无法预分配保留的虚拟机空间,纳米区域被放弃

sta*_*ter 17 xcode objective-c ios swift

从 iOS 14 开始,我的 iOS 应用程序将此错误消息打印到控制台(作为第一条消息)。

AppName(5088,0x1064438c0) malloc: nano zone abandoned due to inability to preallocate reserved vm space.

在 Google 上搜索时我找不到任何其他类似的问题,我不知道是什么原因造成的。我在 iPhone XS Max、iOS 14.0.1、Swift 5 上运行。

mib*_*ibu 35

在深入研究 Apple 的 libmalloc 源代码后,我发现了有问题的函数nano_malloc您可以在Apple 的开源站点查看代码。

从代码中可以看出,nano_malloc调用nano_preallocate_band_vm 预先分配一定量的堆内存(我猜是出于优化目的)。如果内核没有准确地返回地址NANOZONE_SIGNATURE(0x6 << 44),nano_preallocate_band_vm则报告失败 ==>nano_init打印出该消息。

与Linux社区不同,Apple不会对其内部实现发表评论,因此我没有任何权威答案。但这是我的假设:

  1. Libmalloc 预分配内存仅用于优化目的==> 这样做失败不会影响任何程序的结果。
  2. 地址/线程清理程序在 libmalloc 执行之前分配其数据结构 ==> libmalloc 无法在其预期的确切地址获取内存块 ==> 无法预分配。

无论如何,正如源代码所示,Apple 为您提供了 2 种方法来关闭此警告:

  1. Undef NANO_PREALLOCATE_BAND_VM(仅当从源代码编译 libmalloc 时才可行)
  2. 将环境变量设置MallocNanoZone为 0。

我确实尝试了第二个选项并成功了。

仅供参考,这不是 Xcode 或 Swift 的特定问题。我使用 Address Sanitizer 编译了 C/C++ 代码clang -fsanitize=address -o main main.c,该程序发出完全相同的警告,并且相同的解决方案有效。

我的工具版本供将来参考:

$ clang --version
Apple clang version 13.0.0 (clang-1300.0.29.3)
Target: x86_64-apple-darwin21.1.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

$ sw_vers
ProductName:    macOS
ProductVersion: 12.0.1
BuildVersion:   21A559
Run Code Online (Sandbox Code Playgroud)


mur*_*urp 1

尝试执行以下操作:设置活动方案(播放和停止按钮旁边)-> 编辑方案-> 诊断,然后打开“Thread Sanitizer”。启用 Thread Sanitizer 后,错误将被捕获,并且您将在调试器中收到更具描述性的警告。如果描述是 Swift 访问竞争,那么您应该在代码中使用线程安全屏障。

  • 没有回答所提出的问题 (4认同)