I'm creating PDF files on my app, And having a memory issue when merging PDF pages together. After running Instrument Allocations I can see that all the undisposed data is at: private func addPageToMainPdf(left: Bool) -> Bool. The instrument points to the PDFDocument creation within the function, but I can't tell why its not disposed of.
Function using most memory:
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
}
//Supporting Code:
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
So my solution was to use autorelasepool when writing to main document file. I'm not sure why the main document doesn't get released automatically. But this technically fixes the problem. New issue is that this slows the process down by at least 4 times.
_ = autoreleasepool
{
firstPDFDocument.write(to: exportPath().url)
}
If anyone has a solution to speed this up or a faster way to add pages to main pdf document. I'd appreciate it. Using Time Profiler writing to main document line uses 94% of all time for the function.