JetBrains / compose-multiplatform

Compose Multiplatform, a modern UI framework for Kotlin that makes building performant and beautiful user interfaces easy and enjoyable.
https://jetbrains.com/lp/compose-multiplatform
Apache License 2.0
16.25k stars 1.18k forks source link

ComposeUIViewController not released at all #3201

Closed Alex009 closed 1 year ago

Alex009 commented 1 year ago

Describe the bug I embed ComposeUIViewController to native iOS navigation. When i navigate back current ComposeUIViewController should release memory, but it's not.

Affected platforms

Versions

To Reproduce

  1. clone https://github.com/Alex009/compose-ui-vc-leak
  2. run app
  3. navigate back to root (press back at top left corner)
  4. check memory - it's not released
  5. run Simulate memory warning on simulator - you see in logs that many ComposeUIViewController got this warning

Expected behavior ComposeUIViewController should release memory when it's not used by app.

Screenshots

image

Additional context Add any other context about the problem here.

Alex009 commented 1 year ago

i think problem is reference cycle with keyboard observer

https://github.com/JetBrains/compose-multiplatform-core/blob/cf7d6a444f4a5dc6379d49de4c8a0867e738a588/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/window/ComposeWindow.uikit.kt#L119

as i know for K/N difficult to understand cycles between Kotlin & ObjC boundaries

alexzhirkevich commented 1 year ago

Had the same problem. I thought that was my fault of leaked reference somewhere :)

warnyul commented 1 year ago

I have a workaround for this. I just set the ComposeUIViewController.view to an empty UIView.

warnyul commented 1 year ago

But it not solved my original memory leaks. Somewhy lot of IOSurface is stuck in the memory:

Screenshot 2023-05-29 at 23 45 35

Do you experience the same?

elijah-semyonov commented 1 year ago

The problem is pinned down and is related to GC. In this particular case it's resolved via using new Kotlin language feature to manually release native API reference counted objects when their lifetime is critical for correct usage of API (CAMetalDrawable is living for too long and holds IOSurface memory). The latest possible moment the fix arrives is release associated with Kotlin 1.9.0.

elijah-semyonov commented 1 year ago

I found more sources of this leak caused by interaction of GC and ARC-managed memory, to be resolved later

elijah-semyonov commented 1 year ago

The leak of ComposeWindow itself (but not all associated resources) is fixed in this PR

okushnikov commented 2 months ago

Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.