From 657467e4096e6a71ca87cd891bf23da8fb0d8335 Mon Sep 17 00:00:00 2001 From: Kenneth Skovhede Date: Thu, 2 Jul 2026 11:32:54 +0200 Subject: [PATCH] Fix MacOS Photos memory usage This PR fixes a memory usage issue with MacOS Photos integration. Prior to this fix, Duplicati would allow the Photos library to stream an unlimited amount of data. For large files this would require all resources to be kept fully in memory. With this fix, the reader is limited to 8MB read-ahead, such that the maximum size of memory use is bounded by 8MBxReaders, where readers are default cores/2. Additionally, this significantly reduces the memory allocation/deallocation in the C# layer when processing PhotoKit entries. --- .gitignore | 1 + .../Snapshots/MacOS/MacOSPhotosNative.cs | 91 ++++++++++++++---- .../MacOS/MacOSPhotosNativeStream.cs | 6 +- Tools/MacOSPhotosNative/DuplicatiPhotos.m | 77 ++++++++++++--- .../libDuplicatiPhotos.dylib | Bin 158744 -> 159048 bytes 5 files changed, 143 insertions(+), 32 deletions(-) diff --git a/.gitignore b/.gitignore index 769557ef3..4eac4703b 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,4 @@ changelog-news.txt ReleaseBuilder/build-temp/ ReleaseBuilder/Resources/Windows/TrayIcon/binfiles.wxs ReleaseBuilder/Resources/Windows/Agent/binfiles.wxs +Tools/MacOSPhotosNative/build/ diff --git a/Duplicati/Library/Snapshots/MacOS/MacOSPhotosNative.cs b/Duplicati/Library/Snapshots/MacOS/MacOSPhotosNative.cs index e788a496c..dc991498c 100644 --- a/Duplicati/Library/Snapshots/MacOS/MacOSPhotosNative.cs +++ b/Duplicati/Library/Snapshots/MacOS/MacOSPhotosNative.cs @@ -156,27 +156,84 @@ internal static class MacOSPhotosNative if (buffer.Length == 0) return 0; - var errorPtr = IntPtr.Zero; - int bytesRead; - - // TODO: Optimize to read directly into the provided buffer - var tempbuffer = new byte[buffer.Length]; - var result = NativeMethods.DuplicatiPhotosReadAsset(handle, tempbuffer, (nuint)tempbuffer.Length, out errorPtr); - if (result < 0) + // A Span cannot be pinned via a GCHandle, so use a pooled rented array + // as a bounce buffer. Callers that hold an array or Memory use the + // allocation-free overload below. + var rented = System.Buffers.ArrayPool.Shared.Rent(buffer.Length); + try { - var message = ConsumeErrorMessage(ref errorPtr) ?? "Failed to read Photos asset data."; - throw new MacOSPhotosException(message); + var read = ReadIntoArray(handle, rented, 0, buffer.Length); + if (read > 0) + rented.AsSpan(0, read).CopyTo(buffer); + return read; } - tempbuffer.AsSpan(0, (int)result).CopyTo(buffer); - bytesRead = checked((int)result); - - if (errorPtr != IntPtr.Zero) + finally { - NativeMethods.DuplicatiPhotosFreeString(errorPtr); - errorPtr = IntPtr.Zero; + System.Buffers.ArrayPool.Shared.Return(rented); } + } - return bytesRead; + /// + /// Reads data from the asset into the provided buffer + /// + /// The asset handle + /// The buffer to read data into + /// The number of bytes read + internal static int ReadAsset(SafeAssetHandle handle, Memory buffer) + { + if (handle.IsInvalid) + throw new ObjectDisposedException(nameof(SafeAssetHandle)); + + if (buffer.Length == 0) + return 0; + + // Try to read directly into the caller-provided array by pinning it, + // avoiding an intermediate managed allocation on every read. If the + // buffer is not array-backed, fall back to the Span overload, which + // uses a pooled rented array. + if (MemoryMarshal.TryGetArray(buffer, out var segment) && segment.Array != null) + return ReadIntoArray(handle, segment.Array, segment.Offset, segment.Count); + + return ReadAsset(handle, buffer.Span); + } + + /// + /// Reads data into a pinned region of the provided array + /// + /// The asset handle + /// The backing array to read into + /// The offset within the array + /// The number of bytes to read + /// The number of bytes read + private static int ReadIntoArray(SafeAssetHandle handle, byte[] array, int offset, int count) + { + // Pin the array and pass the element address to the native reader. Using + // a pinned GCHandle keeps this allocation-free and does not require the + // project to enable unsafe code blocks. + var gch = GCHandle.Alloc(array, GCHandleType.Pinned); + try + { + var bufferPtr = Marshal.UnsafeAddrOfPinnedArrayElement(array, offset); + var result = NativeMethods.DuplicatiPhotosReadAsset(handle, bufferPtr, (nuint)count, out var errorPtr); + + if (result < 0) + { + var message = ConsumeErrorMessage(ref errorPtr) ?? "Failed to read Photos asset data."; + throw new MacOSPhotosException(message); + } + + if (errorPtr != IntPtr.Zero) + { + NativeMethods.DuplicatiPhotosFreeString(errorPtr); + errorPtr = IntPtr.Zero; + } + + return checked((int)result); + } + finally + { + gch.Free(); + } } /// @@ -355,7 +412,7 @@ internal static class MacOSPhotosNative /// The error message, if any /// The number of bytes read [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern nint DuplicatiPhotosReadAsset(SafeAssetHandle handle, byte[] buffer, nuint length, out IntPtr errorMessage); + internal static extern nint DuplicatiPhotosReadAsset(SafeAssetHandle handle, IntPtr buffer, nuint length, out IntPtr errorMessage); /// /// Closes the asset handle diff --git a/Duplicati/Library/Snapshots/MacOS/MacOSPhotosNativeStream.cs b/Duplicati/Library/Snapshots/MacOS/MacOSPhotosNativeStream.cs index 2c493db23..fca6e6cc5 100644 --- a/Duplicati/Library/Snapshots/MacOS/MacOSPhotosNativeStream.cs +++ b/Duplicati/Library/Snapshots/MacOS/MacOSPhotosNativeStream.cs @@ -71,7 +71,7 @@ internal sealed class MacOSPhotosNativeStream : Stream if (count == 0) return 0; - var bytesRead = MacOSPhotosNative.ReadAsset(handle, new Span(buffer, offset, count)); + var bytesRead = MacOSPhotosNative.ReadAsset(handle, new Memory(buffer, offset, count)); position += bytesRead; return bytesRead; } @@ -92,7 +92,7 @@ internal sealed class MacOSPhotosNativeStream : Stream if (disposed) throw new ObjectDisposedException(nameof(MacOSPhotosNativeStream)); - var bytesRead = MacOSPhotosNative.ReadAsset(handle, buffer.Span); + var bytesRead = MacOSPhotosNative.ReadAsset(handle, buffer); position += bytesRead; return ValueTask.FromResult(bytesRead); } @@ -108,7 +108,7 @@ internal sealed class MacOSPhotosNativeStream : Stream if (count == 0) return Task.FromResult(0); - var bytesRead = MacOSPhotosNative.ReadAsset(handle, new Span(buffer, offset, count)); + var bytesRead = MacOSPhotosNative.ReadAsset(handle, new Memory(buffer, offset, count)); position += bytesRead; return Task.FromResult(bytesRead); } diff --git a/Tools/MacOSPhotosNative/DuplicatiPhotos.m b/Tools/MacOSPhotosNative/DuplicatiPhotos.m index f70511977..f22727fe1 100644 --- a/Tools/MacOSPhotosNative/DuplicatiPhotos.m +++ b/Tools/MacOSPhotosNative/DuplicatiPhotos.m @@ -287,8 +287,22 @@ void DuplicatiPhotosFreeAssets(DuplicatiPhotosAssetMetadata *assets, size_t coun free(assets); } +// Maximum number of bytes that may be buffered in memory before the +// PhotoKit data-received handler is throttled. PhotoKit delivers data on a +// background thread as fast as it can (especially when downloading from +// iCloud), while the managed consumer drains it much more slowly during +// deduplication/compression/upload. Without a cap the entire asset (or many +// concurrent assets) accumulates in memory, which previously led to the +// process being killed by the OS out-of-memory reaper. 8 MiB is a generous +// window that keeps throughput high while bounding memory use. +static const NSUInteger kDuplicatiPhotosMaxBufferBytes = 8 * 1024 * 1024; + @interface DuplicatiPhotosReader : NSObject @property (nonatomic, strong) NSMutableData *buffer; +// Number of bytes at the front of `buffer` that have already been consumed. +// Tracking a read offset avoids repeatedly shifting the whole buffer (and +// avoids NSMutableData holding onto peak capacity) until we compact. +@property (nonatomic, assign) NSUInteger readOffset; @property (nonatomic, strong) NSCondition *condition; @property (nonatomic, assign) BOOL completed; @property (nonatomic, assign) BOOL cancelled; @@ -305,6 +319,7 @@ void DuplicatiPhotosFreeAssets(DuplicatiPhotosAssetMetadata *assets, size_t coun if (self) { _resource = resource; _buffer = [NSMutableData data]; + _readOffset = 0; _condition = [[NSCondition alloc] init]; _completed = NO; _cancelled = NO; @@ -329,9 +344,27 @@ void DuplicatiPhotosFreeAssets(DuplicatiPhotosAssetMetadata *assets, size_t coun DLog(@"DuplicatiPhotos: Received data chunk of size: %lu", (unsigned long)data.length); [strongSelf.condition lock]; - DLog(@"DuplicatiPhotos: Locked condition, current buffer size: %lu, appending data", (unsigned long)strongSelf.buffer.length); + + // Apply back-pressure: if the amount of buffered-but-unread + // data has grown past the cap, block this handler until the + // consumer has drained enough to make room. This throttles + // PhotoKit so it does not read the whole (potentially + // multi-gigabyte) asset into memory ahead of the consumer. + while (!strongSelf.cancelled && + (strongSelf.buffer.length - strongSelf.readOffset) >= kDuplicatiPhotosMaxBufferBytes) { + DLog(@"DuplicatiPhotos: Buffer full (%lu bytes), waiting for consumer to drain", (unsigned long)(strongSelf.buffer.length - strongSelf.readOffset)); + [strongSelf.condition wait]; + } + + if (strongSelf.cancelled) { + DLog(@"DuplicatiPhotos: Cancelled while waiting to append, dropping data"); + [strongSelf.condition unlock]; + return; + } + + DLog(@"DuplicatiPhotos: Locked condition, current unread size: %lu, appending data", (unsigned long)(strongSelf.buffer.length - strongSelf.readOffset)); [strongSelf.buffer appendData:data]; - DLog(@"DuplicatiPhotos: Data appended, new buffer size: %lu", (unsigned long)strongSelf.buffer.length); + DLog(@"DuplicatiPhotos: Data appended, new unread size: %lu", (unsigned long)(strongSelf.buffer.length - strongSelf.readOffset)); [strongSelf.condition signal]; DLog(@"DuplicatiPhotos: Signaled condition, unlocking"); [strongSelf.condition unlock]; @@ -402,14 +435,16 @@ void DuplicatiPhotosFreeAssets(DuplicatiPhotosAssetMetadata *assets, size_t coun DLog(@"DuplicatiPhotos: Locking condition for read on thread %@", [NSThread currentThread]); [self.condition lock]; - DLog(@"DuplicatiPhotos: Condition locked, buffer length: %lu, completed: %d", (unsigned long)self.buffer.length, self.completed); - while (self.buffer.length == 0 && !self.completed) { + NSUInteger available = self.buffer.length - self.readOffset; + DLog(@"DuplicatiPhotos: Condition locked, available: %lu, completed: %d", (unsigned long)available, self.completed); + while (available == 0 && !self.completed) { DLog(@"DuplicatiPhotos: Waiting for data..."); [self.condition wait]; - DLog(@"DuplicatiPhotos: Woke up from wait, buffer length: %lu, completed: %d", (unsigned long)self.buffer.length, self.completed); + available = self.buffer.length - self.readOffset; + DLog(@"DuplicatiPhotos: Woke up from wait, available: %lu, completed: %d", (unsigned long)available, self.completed); } - if (self.buffer.length == 0) { + if (available == 0) { DLog(@"DuplicatiPhotos: Buffer is empty after wait"); NSError *error = self.error; [self.condition unlock]; @@ -426,12 +461,30 @@ void DuplicatiPhotosFreeAssets(DuplicatiPhotosAssetMetadata *assets, size_t coun return 0; } - size_t toCopy = MIN((size_t)self.buffer.length, length); - DLog(@"DuplicatiPhotos: Copying %zu bytes to destination from buffer of size %lu", toCopy, (unsigned long)self.buffer.length); - memcpy(destination, self.buffer.bytes, toCopy); - DLog(@"DuplicatiPhotos: memcpy completed, removing copied bytes from buffer"); - [self.buffer replaceBytesInRange:NSMakeRange(0, toCopy) withBytes:NULL length:0]; - DLog(@"DuplicatiPhotos: Buffer updated, new size: %lu, unlocking", (unsigned long)self.buffer.length); + size_t toCopy = MIN((size_t)available, length); + DLog(@"DuplicatiPhotos: Copying %zu bytes to destination from available %lu", toCopy, (unsigned long)available); + memcpy(destination, (const uint8_t *)self.buffer.bytes + self.readOffset, toCopy); + self.readOffset += toCopy; + DLog(@"DuplicatiPhotos: memcpy completed, advancing read offset to %lu", (unsigned long)self.readOffset); + + // Reclaim memory. If everything buffered so far has been consumed, reset + // the buffer to zero length (releasing peak capacity). Otherwise, once the + // consumed prefix grows large, drop it from the front so the backing store + // does not grow without bound for large assets. Using a read offset avoids + // shifting bytes on every single read. + if (self.readOffset == self.buffer.length) { + self.buffer.length = 0; + self.readOffset = 0; + DLog(@"DuplicatiPhotos: Buffer fully drained, reset to empty"); + } else if (self.readOffset >= kDuplicatiPhotosMaxBufferBytes) { + [self.buffer replaceBytesInRange:NSMakeRange(0, self.readOffset) withBytes:NULL length:0]; + self.readOffset = 0; + DLog(@"DuplicatiPhotos: Compacted buffer, new size: %lu", (unsigned long)self.buffer.length); + } + + // Wake the (possibly throttled) data-received handler now that space is free. + [self.condition signal]; + DLog(@"DuplicatiPhotos: Signaled producer, unlocking, new unread size: %lu", (unsigned long)(self.buffer.length - self.readOffset)); [self.condition unlock]; DLog(@"DuplicatiPhotos: Returning %zd bytes", (ssize_t)toCopy); return (ssize_t)toCopy; diff --git a/Tools/MacOSPhotosNative/libDuplicatiPhotos.dylib b/Tools/MacOSPhotosNative/libDuplicatiPhotos.dylib index 998f992b893affb66dd9321de192585718420d35..5b8f19858dd83f77eb782e77f32ef1d30554c361 100755 GIT binary patch delta 41070 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