在文档中生成超过 58 个 PDF 页面时应用程序终止(内存问题?)Swift
App Terminates when generating more than 58 PDF pages in a document (Memory Issue?) Swift
我正在我的应用程序上创建 PDF 文件,在合并 PDF 页面时遇到内存问题。在 运行 Instrument Allocations 之后,我可以看到所有未处理的数据位于:private func addPageToMainPdf(left: Bool) -> Bool。仪器指向函数内的PDFDocument创建,但我不知道为什么它没有被处理掉。
使用内存最多的函数:
private func addPageToMainPdf(left: Bool) -> Bool //MEMORY LEAK
{
if left
{
if let firstPDFDocument = PDFDocument(url: exportPath().url)
{
let pages = firstPDFDocument.pageCount
if let secondPDFDocument = PDFDocument(url: exportPathLeft().url)
{
if let page = secondPDFDocument.page(at: 0)
{
firstPDFDocument.insert(page, at: pages)
firstPDFDocument.write(to: exportPath().url) // Uses gigabytes of exponential memory until app crashes, release pool fixes the problem but function takes at least 4 times as long now.
return true
}
}
}
}//cropped out rest of the code for right pages for other files
}
//支持代码:
func exportPath() -> (url: URL, string: String, fileName: String)
{
let fileName = "MasterFile.pdf"
let Manager = FileManager.default
let fileURL = try! Manager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true).appendingPathComponent(fileName)
return (fileURL, fileURL.path, fileName)
}
private func exportPathLeft() -> (url: URL, string: String, fileName: String)
{
let fileName = "tempLeft.pdf"
let Manager = FileManager.default
let fileURL = try! Manager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true).appendingPathComponent(fileName)
return (fileURL, fileURL.path, fileName)
}
iOSAppName(22955,0x16e277000) malloc: can't allocate region
:*** mach_vm_map(size=262144, flags: 100) failed (error code=3)
iOSAppName(22955,0x16e277000) malloc: *** set a breakpoint in malloc_error_break to debug
iOSAppName(22955,0x16e277000) malloc: can't allocate region
:*** mach_vm_map(size=262144, flags: 100) failed (error code=3)
iOSAppName(22955,0x16e277000) malloc: *** set a breakpoint in malloc_error_break to debug
2021-02-26 21:45:15.540187+0000 iOSAppName[22955:11122435] *** Terminating app due to uncaught exception 'NSMallocException', reason: 'Failed to grow buffer'
*** First throw call stack:
(0x1ac64c878 0x1c0ba2c50 0x1ac6c2518 0x1ac6b977c 0x1ac561088 0x1ac586e68 0x1ac586c70 0x1adfd35b0 0x1ae1b75fc 0x1adeddf84 0x1adf163dc 0x1adf161a8 0x1ae1b26c8 0x1ae094b7c 0x1ae0948a8 0x1adfddc78 0x1ae1f8b64 0x1ae1f9164 0x1ade9f434 0x1ade9fc78 0x1df4c1114 0x1df4c0eac 0x1df4abb5c 0x1df4b0d84 0x102634d24 0x102655848 0x10260d998 0x102403814 0x1022ebda8 0x10219eiOSAppName(22955,0x16e277000) malloc: can't allocate region
:*** mach_vm_map(size=262144, flags: 100) failed (error code=3)
iOSAppName(22955,0x16e277000) malloc: *** set a breakpoint in malloc_error_break to debug
iOSAppName(22955,0x16e277000) malloc: can't allocate region
:*** mach_vm_map(size=262144, flags: 100) failed (error code=3)
iOSAppName(22955,0x16e277000) malloc: *** set a breakpoint in malloc_error_break to debug
2021-02-26 21:45:15.540187+0000 iOSAppName[22955:11122435] *** Terminating app due to uncaught exception 'NSMallocException', reason: 'Failed to grow buffer'
*** First throw call stack:
(0x1ac64c878 0x1c0ba2c50 0x1ac6c2518 0x1ac6b977c 0x1ac561088 0x1ac586e68 0x1ac586c70 0x1adfd35b0 0x1ae1b75fc 0x1adeddf84 0x1adf163dc 0x1adf161a8 0x1ae1b26c8 0x1ae094b7c 0x1ae0948a8 0x1adfddc78 0x1ae1f8b64 0x1ae1f9164 0x1ade9f434 0x1ade9fc78 0x1df4c1114 0x1df4c0eac 0x1df4abb5c 0x1df4b0d84 0x102634d24 0x102655848 0x10260d998 0x102403814 0x1022ebda8 0x10219e654 0x10809fbcc 0x1080a16c0 0x1080a40ec 0x1080b4ae0 0x1080b5488 0x1f5a647c8 0x1f5a6b75c)
libc++abi.dylib: terminating with uncaught exception of type NSException
warning: could not execute support code to read Objective-C class data in the process. This may reduce the quality of type information available.
*** Terminating app due to uncaught exception 'NSMallocException', reason: 'Failed to grow buffer'
terminating with uncaught exception of type NSException654 0x10809fbcc 0x1080a16c0 0x1080a40ec 0x1080b4ae0 0x1080b5488 0x1f5a647c8 0x1f5a6b75c)
libc++abi.dylib: terminating with uncaught exception of type NSException
warning: could not execute support code to read Objective-C class data in the process. This may reduce the quality of type information available.
*** Terminating app due to uncaught exception 'NSMallocException', reason: 'Failed to grow buffer'
terminating with uncaught exception of type NSException
所以我的解决方案是在写入主文档文件时使用 autorelasepool。我不确定为什么主文档没有自动发布。但这在技术上解决了这个问题。新问题是这会使过程至少减慢 4 倍。
_ = autoreleasepool
{
firstPDFDocument.write(to: exportPath().url)
}
如果有人有加速此过程的解决方案或更快地将页面添加到主 pdf 文档的方法。我会很感激。使用 Time Profiler 写入主文档行将 94% 的时间用于函数。
我正在我的应用程序上创建 PDF 文件,在合并 PDF 页面时遇到内存问题。在 运行 Instrument Allocations 之后,我可以看到所有未处理的数据位于:private func addPageToMainPdf(left: Bool) -> Bool。仪器指向函数内的PDFDocument创建,但我不知道为什么它没有被处理掉。
使用内存最多的函数:
private func addPageToMainPdf(left: Bool) -> Bool //MEMORY LEAK
{
if left
{
if let firstPDFDocument = PDFDocument(url: exportPath().url)
{
let pages = firstPDFDocument.pageCount
if let secondPDFDocument = PDFDocument(url: exportPathLeft().url)
{
if let page = secondPDFDocument.page(at: 0)
{
firstPDFDocument.insert(page, at: pages)
firstPDFDocument.write(to: exportPath().url) // Uses gigabytes of exponential memory until app crashes, release pool fixes the problem but function takes at least 4 times as long now.
return true
}
}
}
}//cropped out rest of the code for right pages for other files
}
//支持代码:
func exportPath() -> (url: URL, string: String, fileName: String)
{
let fileName = "MasterFile.pdf"
let Manager = FileManager.default
let fileURL = try! Manager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true).appendingPathComponent(fileName)
return (fileURL, fileURL.path, fileName)
}
private func exportPathLeft() -> (url: URL, string: String, fileName: String)
{
let fileName = "tempLeft.pdf"
let Manager = FileManager.default
let fileURL = try! Manager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true).appendingPathComponent(fileName)
return (fileURL, fileURL.path, fileName)
}
iOSAppName(22955,0x16e277000) malloc: can't allocate region
:*** mach_vm_map(size=262144, flags: 100) failed (error code=3)
iOSAppName(22955,0x16e277000) malloc: *** set a breakpoint in malloc_error_break to debug
iOSAppName(22955,0x16e277000) malloc: can't allocate region
:*** mach_vm_map(size=262144, flags: 100) failed (error code=3)
iOSAppName(22955,0x16e277000) malloc: *** set a breakpoint in malloc_error_break to debug
2021-02-26 21:45:15.540187+0000 iOSAppName[22955:11122435] *** Terminating app due to uncaught exception 'NSMallocException', reason: 'Failed to grow buffer'
*** First throw call stack:
(0x1ac64c878 0x1c0ba2c50 0x1ac6c2518 0x1ac6b977c 0x1ac561088 0x1ac586e68 0x1ac586c70 0x1adfd35b0 0x1ae1b75fc 0x1adeddf84 0x1adf163dc 0x1adf161a8 0x1ae1b26c8 0x1ae094b7c 0x1ae0948a8 0x1adfddc78 0x1ae1f8b64 0x1ae1f9164 0x1ade9f434 0x1ade9fc78 0x1df4c1114 0x1df4c0eac 0x1df4abb5c 0x1df4b0d84 0x102634d24 0x102655848 0x10260d998 0x102403814 0x1022ebda8 0x10219eiOSAppName(22955,0x16e277000) malloc: can't allocate region
:*** mach_vm_map(size=262144, flags: 100) failed (error code=3)
iOSAppName(22955,0x16e277000) malloc: *** set a breakpoint in malloc_error_break to debug
iOSAppName(22955,0x16e277000) malloc: can't allocate region
:*** mach_vm_map(size=262144, flags: 100) failed (error code=3)
iOSAppName(22955,0x16e277000) malloc: *** set a breakpoint in malloc_error_break to debug
2021-02-26 21:45:15.540187+0000 iOSAppName[22955:11122435] *** Terminating app due to uncaught exception 'NSMallocException', reason: 'Failed to grow buffer'
*** First throw call stack:
(0x1ac64c878 0x1c0ba2c50 0x1ac6c2518 0x1ac6b977c 0x1ac561088 0x1ac586e68 0x1ac586c70 0x1adfd35b0 0x1ae1b75fc 0x1adeddf84 0x1adf163dc 0x1adf161a8 0x1ae1b26c8 0x1ae094b7c 0x1ae0948a8 0x1adfddc78 0x1ae1f8b64 0x1ae1f9164 0x1ade9f434 0x1ade9fc78 0x1df4c1114 0x1df4c0eac 0x1df4abb5c 0x1df4b0d84 0x102634d24 0x102655848 0x10260d998 0x102403814 0x1022ebda8 0x10219e654 0x10809fbcc 0x1080a16c0 0x1080a40ec 0x1080b4ae0 0x1080b5488 0x1f5a647c8 0x1f5a6b75c)
libc++abi.dylib: terminating with uncaught exception of type NSException
warning: could not execute support code to read Objective-C class data in the process. This may reduce the quality of type information available.
*** Terminating app due to uncaught exception 'NSMallocException', reason: 'Failed to grow buffer'
terminating with uncaught exception of type NSException654 0x10809fbcc 0x1080a16c0 0x1080a40ec 0x1080b4ae0 0x1080b5488 0x1f5a647c8 0x1f5a6b75c)
libc++abi.dylib: terminating with uncaught exception of type NSException
warning: could not execute support code to read Objective-C class data in the process. This may reduce the quality of type information available.
*** Terminating app due to uncaught exception 'NSMallocException', reason: 'Failed to grow buffer'
terminating with uncaught exception of type NSException
所以我的解决方案是在写入主文档文件时使用 autorelasepool。我不确定为什么主文档没有自动发布。但这在技术上解决了这个问题。新问题是这会使过程至少减慢 4 倍。
_ = autoreleasepool
{
firstPDFDocument.write(to: exportPath().url)
}
如果有人有加速此过程的解决方案或更快地将页面添加到主 pdf 文档的方法。我会很感激。使用 Time Profiler 写入主文档行将 94% 的时间用于函数。