自iOS 14以来,我的iOS应用程序将此错误消息打印到控制台(作为第一条消息)。AppName(5088,0x1064438c0) malloc: nano zone abandoned due to inability to preallocate reserved vm space.我在谷歌上搜索时找不到任何其他类似的问题,我不知道是什么原因造成的.我正在运行iPhone XS Max,iOS 14.0.1,Swift 5.
AppName(5088,0x1064438c0) malloc: nano zone abandoned due to inability to preallocate reserved vm space.
mwkjh3gx1#
在深入研究了苹果的libmalloc源代码之后,我发现了一个令人不快的函数nano_malloc,您可以在苹果的开源网站here上查看该代码。从代码中可以看到,nano_malloc调用nano_preallocate_band_vm来预分配一定数量的堆内存(我猜是为了优化),如果内核没有返回一个精确的地址NANOZONE_SIGNATURE(0x 6〈〈44),nano_preallocate_band_vm报告失败==〉nano_init打印出消息。不像Linux社区,苹果不评论他们的内部实现,所以我没有任何权威的答案。但这里是我的假设:
nano_malloc
nano_preallocate_band_vm
NANOZONE_SIGNATURE
nano_init
NANO_PREALLOCATE_BAND_VM
MallocNanoZone
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
f1tvaqid2#
尝试访问:设置活动方案(在播放和停止按钮旁边)-〉编辑方案-〉诊断,然后打开“线程消毒器”。2在线程消毒器打开的情况下,错误将被捕获,并且您将收到一个在调试器中更具描述性的警告。3如果描述是快速访问竞争,那么您应该在代码中使用线程安全屏障。
8ftvxx2r3#
我不知道你是如何构建代码的,但在我的例子中,我所做的只是在代码中添加了一个do try catch。
do try catch
static func fetchAlbumWithAsyncURLSession() async throws -> [Album] { guard let url = URL(string: "https://itunes.apple.com/search?term=taylor+swift&entity=album") else { throw AlbumsFetcherError.invalidURL } let (data, _) = try await URLSession.shared.data(from: url) let iTunesResult = try JSONDecoder().decode(ITunesResult.self, from: data) return iTunesResult.results }
变成这样:
static func fetchAlbumWithAsyncURLSession() async throws -> [Album] { guard let url = URL(string: "https://itunes.apple.com/search?term=taylor+swift&entity=album") else { throw AlbumsFetcherError.invalidURL } do { let (data, _) = try await URLSession.shared.data(from: url) let iTunesResult = try JSONDecoder().decode(ITunesResult.self, from: data) return iTunesResult.results } catch { print("Request failed with error: \(error)") return [] } }
然后我得到了错误:D最好的问候!
a14dhokn4#
我注意到这个错误会在运行时清理下的项目方案的诊断选项中出现和消失:螺纹消毒剂
4条答案
按热度按时间mwkjh3gx1#
在深入研究了苹果的libmalloc源代码之后,我发现了一个令人不快的函数
nano_malloc
,您可以在苹果的开源网站here上查看该代码。从代码中可以看到,
nano_malloc
调用nano_preallocate_band_vm
来预分配一定数量的堆内存(我猜是为了优化),如果内核没有返回一个精确的地址NANOZONE_SIGNATURE
(0x 6〈〈44),nano_preallocate_band_vm
报告失败==〉nano_init
打印出消息。不像Linux社区,苹果不评论他们的内部实现,所以我没有任何权威的答案。但这里是我的假设:
1.地址/线程清理程序在libmalloc完成之前分配它们的数据结构==〉libmalloc无法获取准确地址的内存块,因为它预期==〉未能预分配。
无论如何,正如源代码所示,苹果给予你两种方法来关闭这个警告:
NANO_PREALLOCATE_BAND_VM
(仅在从源代码编译libmalloc时可用)1.将环境变量
MallocNanoZone
设置为0。我确实尝试了第二种选择,并取得了成功。
顺便说一句,这不是Xcode或Swift的特定问题。我用地址消毒器
clang -fsanitize=address -o main main.c
编译了C/C++代码,程序发出完全相同的警告,相同的解决方案起作用。我的工具版本(供将来参考):
f1tvaqid2#
尝试访问:设置活动方案(在播放和停止按钮旁边)-〉编辑方案-〉诊断,然后打开“线程消毒器”。2在线程消毒器打开的情况下,错误将被捕获,并且您将收到一个在调试器中更具描述性的警告。3如果描述是快速访问竞争,那么您应该在代码中使用线程安全屏障。
8ftvxx2r3#
我不知道你是如何构建代码的,但在我的例子中,我所做的只是在代码中添加了一个
do try catch
。变成这样:
然后我得到了错误:D
最好的问候!
a14dhokn4#
关闭方案中的线程消毒程序
我注意到这个错误会在运行时清理下的项目方案的诊断选项中出现和消失:螺纹消毒剂