Coder Social home page Coder Social logo

Comments (7)

kean avatar kean commented on June 14, 2024 1

One more thing you can try is enabling isUsingPrepareForDisplay. It then switches to use the native prepareForDisplay method for decompression. It's disabled by default because there've been multiple reports of it causing issues in earlier iOS versions. It's probably a good time to revisit it and see if it can be enabled by default. Apple recently added a bunch of error logs when you use it for formats that don't require decompression, so it makes it very hard to use now.

from nuke.

lucasecf avatar lucasecf commented on June 14, 2024 1

Update: we tried to release a version with the isUsingPrepareForDisplay and seems like it still has issues 😓 .

It's not super significant as well, but seems to happen twice as much as the original one (so it's affecting ~0.4% users).

I tried now setting the isDecompressionEnabled to false, which avoids both crashes. There seems to be no much difference in CPU usage, but looks like the memory consumption increases quite drastically.

Any other advices?


14 ourApp                         0x7676d0 UIImage.decompressed(isUsingPrepareForDisplay:) + 151 (Graphics.swift:151)
15 ourApp                         0x77fb58 specialized ImagePipelineDelegate.decompress(response:request:pipeline:) + 10 (ImageDecompression.swift:10)
16 ourApp                         0x79b830 closure #1 in TaskLoadImage.decompressImage(_:isCompleted:isFromDiskCache:) + 202 (TaskLoadImage.swift:202)
17 ourApp                         0x772004 thunk for @escaping @callee_guaranteed @Sendable () -> () + 4341030916 (<compiler-generated>:4341030916)

full stack trace:

NSOperationQueue 0x13cbc8b60 (QOS: UNSPECIFIED)
0  libsystem_kernel.dylib         0x1b7c __psynch_cvwait + 8
1  libsystem_pthread.dylib        0xfd4 _pthread_cond_wait + 1228
2  CoreMedia                      0x2540 WaitOnCondition + 20
3  CoreMedia                      0x2484 FigSemaphoreWaitRelative + 164
4  VideoToolbox                   0x30e068 VTDecompressionSessionRemote_DecodeTile + 576
5  CMPhoto                        0x15b70 VTTileDecompressionPluginClass_decode + 376
6  CMPhoto                        0x1b974 _decodeItem + 6008
7  CMPhoto                        0xb78c _applyDecodeStrategy + 396
8  CMPhoto                        0x7055c _decodeImage + 452
9  CMPhoto                        0x6c564 _createImageForIndex + 804
10 CMPhoto                        0x273b0 CMPhotoDecompressionContainerCreateImageForIndex + 280
11 UIKitCore                      0xa361ec -[_UINewCGImageDecompressor waitForImageRef] + 160
12 UIKitCore                      0x85acdc -[_UIImageCGImageContent contentPreparedForDisplay] + 84
13 UIKitCore                      0x9f7638 -[UIImage imageByPreparingForDisplay] + 28
14 ourApp                         0x7676d0 UIImage.decompressed(isUsingPrepareForDisplay:) + 151 (Graphics.swift:151)
15 ourApp                         0x77fb58 specialized ImagePipelineDelegate.decompress(response:request:pipeline:) + 10 (ImageDecompression.swift:10)
16 ourApp                         0x79b830 closure #1 in TaskLoadImage.decompressImage(_:isCompleted:isFromDiskCache:) + 202 (TaskLoadImage.swift:202)
17 ourApp                         0x772004 thunk for @escaping @callee_guaranteed @Sendable () -> () + 4341030916 (<compiler-generated>:4341030916)
18 Foundation                     0x49c00 __NSBLOCKOPERATION_IS_CALLING_OUT_TO_A_BLOCK__ + 24
19 Foundation                     0x7b0ec -[NSBlockOperation main] + 104
20 Foundation                     0x78974 __NSOPERATION_IS_INVOKING_MAIN__ + 16
21 Foundation                     0x77a64 -[NSOperation start] + 648
22 Foundation                     0x7a57c __NSOPERATIONQUEUE_IS_STARTING_AN_OPERATION__ + 16
23 Foundation                     0x7a2e8 __NSOQSchedule_f + 172
24 libdispatch.dylib              0x13250 _dispatch_block_async_invoke2 + 148
25 libdispatch.dylib              0x4300 _dispatch_client_callout + 20
26 libdispatch.dylib              0x77b8 _dispatch_continuation_pop + 600
27 libdispatch.dylib              0x6dd4 _dispatch_async_redirect_invoke + 584
28 libdispatch.dylib              0x15be4 _dispatch_root_queue_drain + 392
29 libdispatch.dylib              0x163ec _dispatch_worker_thread2 + 156
30 libsystem_pthread.dylib        0x1928 _pthread_wqthread + 228
31 libsystem_pthread.dylib        0x1a04 start_wqthread + 8

EDIT: to elaborate in the memory consumption part - this seems to be kind of an unexpected outcome?

From the description, I understand that the decompression step is meant to improve CPU performance (and achieve smoother scrolling), but turns out Nuke's implementation when using isUsingPrepareForDisplay = false has a 30% less memory usage compared to either isUsingPrepareForDisplay = true or isDecompressionEnabled = false, which basically have the same memory footprint 🤔

After scrolling ~180 products/images on a single screen
isUsingPrepareForDisplay = true isUsingPrepareForDisplay = false

from nuke.

kean avatar kean commented on June 14, 2024

Hey, thanks for the report!

Not sure if relevant, but the image format we are using is avif.

If you find a way to reproduce it, that would be fantastic.

until we wait for Apple to fix it (if ever)?

A Feedback report may help.

from nuke.

lucasecf avatar lucasecf commented on June 14, 2024

Thanks for you reply!

If you find a way to reproduce it, that would be fantastic.

I spent hours on it, but unfortunately could experience the crash only once (when I took the screenshot). It's not a deterministic crash, i.e., the exact same place/image that caused the crash wouldn't do so on next runs.
Seems like some kind of random memory corruption, so really hard to reproduce, otherwise numbers would be higher.

For now I guess it would help to know if there's any way to avoid this call, or if it's something mandatory in the download pipeline

A Feedback report may help.

yeah, will open a radar

from nuke.

kean avatar kean commented on June 14, 2024

You can pass skipDecompression option for any avif images and see if it fixes it. But I see HEIFReadPlugin::decodeImageImp in the crash log, so it may actually be HEIF that's causing the issue.

from nuke.

lucasecf avatar lucasecf commented on June 14, 2024

But I see HEIFReadPlugin::decodeImageImp in the crash log, so it may actually be HEIF that's causing the issue.

Interesting, haven't noticed before. That's weird, because I'm quite positive we don't load HEIF images on our app (checked on monitoring all content types of all network requests). I can only imagine that under the hood this code is shared when the image data is from another format and/or the image data is miscategorised. Since the code is private, I wonder if there's any easy way to check/confirm that.


One more thing you can try is enabling isUsingPrepareForDisplay. It then switches to use the native prepareForDisplay method for decompression. It's disabled by default because there've been multiple reports of it causing issues in earlier iOS versions. It's probably a good time to revisit it and see if it can be enabled by default. Apple recently added a bunch of error logs when you use it for formats that don't require decompression, so it makes it very hard to use now.

That sounds great and seems like what I was looking for. Since it avoids the the CoreGraphics code it should fix our issue, and I can also report here if any other issue happens or not as side effect.

PS: I also filed the bug report with Apple, can post here if there's ever any feedback, but we know how this things goes...

from nuke.

lucasecf avatar lucasecf commented on June 14, 2024

We released a version using skipDecompression option and now all the crashes are gone, since it avoids the CoreGraphacs problematic code.

Like said above, unfortunately this has the side effect of increased memory consumption, so we will keep an eye to revert this change if/when Apple ever fixes the issue.

I'm closing this issue to avoid it hanging forever in the repo. Thanks @kean for the support!

from nuke.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.