Is there a way to limit the maximum unmanaged memory allocated ? #2829
-
Hello, I'm working on a worker that process images, one at the time, we have lots of image so we need to spawn the worker multiple time, most of the image we process are relatively small like ~10Mpixel but sometime we have larger image. To reduce cost we have 2 worker configuration, one worker with a lot of instance using a small memory footprint, and a few worker for the rare case where we have to process big image. To detect large image we set up a limit on the memory allocator, which work well if I have an image that would use more than 384 MB of ram for the buffer, it fail with a nice error message var configuration = Configuration.Default.Clone();
configuration.MemoryAllocator = MemoryAllocator.Create(new MemoryAllocatorOptions
{
MaximumPoolSizeMegabytes = 384,
AllocationLimitMegabytes = 384,
}
);
var image = Image.Load(new DecoderOptions
{
Configuration = configuration,
MaxFrames = 1,
},
stream
); But lately I discover that sometimes 1GB of unmanaged memory where allocated during the decompression of a JPEG file (9 000 x 12 000) I was expecting the And maybe it's normal, I know very little about jpeg decoding, but 1GB to decode a 320MB images feels stange, is it normal ? (No need for details I just want to raise this in case this is not supposed to happen) |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 9 replies
-
Beta Was this translation helpful? Give feedback.
-
Hi @Socolin sorry for the slow reply. We're currently able to restrict allocation for individual memory requests however setting a maximum limit would require tracking multiple requests operationally. It's very likely that ImageMagick is making less and larger requests which hit the lower limit, but we are making more smaller requests which accumulate. I'm not sure we could perform that accumulative tracking in a reasonable manner. If we were to do so it would have to be something that limited memory allocation across all transactions on all threads. @antonfirsov What are your thoughts here? We already track totally allocations via MemoryDiagnostics Do you think applying such a limit is reasonable from a usage perspective or should users suse our Identify methods to weed out input that would hit our limits. I'm not convinced from a development perspective having a limit in place that could be unknowingly hit would be a great experience. |
Beta Was this translation helpful? Give feedback.
SimpleGcMemoryAllocator
might give you what you want, but it will hurt performance.Another workaround that just came into my mind is to implement a tracking allocator that wraps
MemoryAllocator.Default
.Here is a poorly tested prototype:
https://gist.github.com/antonfirsov/05ce2d02a04134ab0879a19c345ed71e
Does this look like a reasonable workaround?