Opening and closing the session details screen repeatedly causes the app to crash with an OOM error.
See original GitHub issueDescribe the bug I don’t know how to deal with this yet without further investigation, but the titular phenomenon occurs.
To Reproduce
- open the Session List screen
- display the session details screen one by one and return to it
- continue to do 2. although the operation becomes slower
- finally, no more operations are accepted and OOM error occurs and the app crashes
Expected behavior
- the screen does not get choppy when opening the session details screen
- no matter how many times I open the session detail screen, the app does not crash with an OOM error
Screenshots
FATAL EXCEPTION: OkHttp Dispatcher
Process: io.github.droidkaigi.confsched2022.dev, PID: 20572
java.lang.OutOfMemoryError: Failed to allocate a 370792 byte allocation with 76488 free bytes and 74KB until OOM, target footprint 268435456, growth limit 268435456
at java.lang.StringFactory.newStringFromUtf8Bytes(Native Method)
at java.lang.StringFactory.newStringFromBytes(StringFactory.java:80)
at java.lang.StringFactory.newStringFromBytes(StringFactory.java:101)
at okio.Buffer.readString(Buffer.kt:313)
at okio.Buffer.readString(Buffer.kt:302)
at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.kt:270)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp(RealCall.kt:201)
at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:517)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1137)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)
at java.lang.Thread.run(Thread.java:1012)
2022-09-16 23:33:01.011 20572-20733 Process io.....droidkaigi.confsched2022.dev I Sending signal. PID: 20572 SIG: 9
---------------------------- PROCESS ENDED (20572) for package io.github.droidkaigi.confsched2022.dev ----------------------------
Issue Analytics
- State:
- Created a year ago
- Comments:7 (7 by maintainers)
Top Results From Across the Web
What are Out Of Memory (OOM) Crashes and How to Avoid ...
Here are some tips and best practices you can use to reduce your app's memory footprint and eliminate OOMs.
Read more >The case of iOS OOM Crashes at Compass - Medium
An OOM crash occurs anytime an app is killed by the system because it over-used RAM, when the OS decided to reclaim the...
Read more >Zoom keeps crashing when someone shares their screen
My Zoom keeps crashing whenever someone in the meeting shares their screen. It usually happens when the number of people in the meeting...
Read more >My VS code keeps crashing when opening it - Stack Overflow
The solution was to start VS Code from the command prompt with the following command: code --disable-extensions --max-memory=12288mb.
Read more >Apps crash randomly on newly installed ubuntu 22.04
I had the same problem, and it turned out that systemd-oomd (a userspace out-of-memory (OOM) killer) was killing my applications whenever I ...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
One interesting observation: Using
lambda
in the click callbacks may result in more and more allocations in the memory when you go back and forth.For example:
DrawerSheetContent.onClickDrawerItem
using lambda will allocate new objects everytime you click a Session to open its detail, and go back. Below is the memory dump between 0 click and 10 clicks (open the Session and go back):NOTE: it seems that Andriod Studio EE doesn’t show the correct value of
Retained Size
. Profiling the App in Android Studio Dolphin gives you the correct number.By changing lambda to method reference, I can see no new objects are allocated by the clicks. The code change is below:
Memory dump of the same suspicious object after opening a Session 0 times and 10 times: (Notice how the total allocation counts are changed significantly, but the number of the highlighted object is the same).
I just try with one lambda in this case, I think if we double check all other places, we can optimize it further. Though it can just be a part of the whole OOM problem.
@Corvus400 @takahirom Not a big progress, but some investigation result:
Stable
object and then the lambda is not memorized correctly, causing it to be re-composed everytime theselectedDrawerItem
changes.https://user-images.githubusercontent.com/1776230/192099224-c35597fa-0f3d-4d68-9e41-78407b35381f.mov
DrawerSheetContent.onClickDrawerItem
to method reference. This time, it is a stable type and only the top Navigation item is re-composed (see video).https://user-images.githubusercontent.com/1776230/192099340-a83b5bee-b8b6-4d55-b1e2-ca599af90732.mov
So at least using method reference can improve the composing performance a little bit. I still see memory usage increasing, so the ultimate solution is not done yet.
I will send a small PR to change this callback to method reference. But keep in mind that it may not fix this issue completely 🙇 .
Additional observation:
I’m curious why opening the session detail will recompose the drawer’s item, and what I learned is that the Session NavGraph is at the same NavGraph as the Drawer’s NavGraph. So if I open the Session detail, it updates the Drawer’s navigation destination and therefore updates the
selectedDrawerItem
--> recompose the Drawer:Maybe we can use nested NavGraph for some Drawer items, such as the Sessions screen, so that navigating within a nested Graph doesn’t recompose the Drawer (see below):
https://user-images.githubusercontent.com/1776230/192099578-1f17d142-a76f-4c6c-9365-799d4b88706a.mov
An important note: simply changing to nested graph doesn’t work out of the box. The reason is:
This observation and update proposal may not be impactful enough to refactor. So this is just a discussion point. If I were to design the navigation structure from the beginning, I would consider using nested graph where it is reasonable 😃 .