sk22 / megalodon

Pink modification of the official Mastodon for Android app
https://sk22.github.io/megalodon
GNU General Public License v3.0
551 stars 32 forks source link

[Bug] Crash after scrolling timelines for a while #964

Open Leah96xxx opened 10 months ago

Leah96xxx commented 10 months ago

Describe the bug

After scrolling through the timelines for a while, Megalodon will start dropping frames, freeze, then crash to home screen. I have tried reinstalling the app and have confirmed that the issue doesn't exist on the official Mastodon app.

This can happen on any timeline. I typically notice this after the app has been running for a coupe of hours.

Looks to me like it's running out of memory, but a dev may be able to advise better. Other apps and the rest of my phone system are unaffected.

Running on a Galaxy S22 Ultra, Android 14, OneUI 6.0

To reproduce

Steps to reproduce the behavior:

  1. Open Megalodon
  2. Scroll through any timeline for a while
  3. Witness app start dropping frames, freeze, then crash.

Does this happen in the official app?

No (Mastodon Play Store latest)

Screenshots and screen recordings

Recording below was captured just after I noticed frame drops.

https://github.com/sk22/megalodon/assets/88419550/2d693e40-3716-4062-abaa-83b25f09e9ca

Version

Megalodon version: 2.1.6+fork.110 (110) (Play Store latest)

Crash log

Click for log > ``` > 2.1.6+fork.110 (110) > 2024-01-11T11:07:24.987Z > > java.lang.OutOfMemoryError: Failed to allocate a 56 byte allocation with 70496 free bytes and 68KB until OOM, target footprint 536870912, growth limit 536870912; giving up on allocation because <1% of heap free after GC. > at android.net.Uri.parse(Uri.java:466) > at me.grishka.appkit.imageloader.requests.UrlImageLoaderRequest.(SourceFile:44) > at org.joinmastodon.android.ui.CustomEmojiPopupKeyboard$SingleCategoryAdapter.lambda$new$0(SourceFile:242) > at org.joinmastodon.android.ui.CustomEmojiPopupKeyboard$SingleCategoryAdapter.$r8$lambda$4MiXBTpf0wNyHQhD-Wq1Y-nOQpU(SourceFile:0) > at org.joinmastodon.android.ui.CustomEmojiPopupKeyboard$SingleCategoryAdapter$$ExternalSyntheticLambda0.apply(SourceFile:0) > at j$.util.stream.f2.accept(SourceFile:0) > at j$.util.a.forEachRemaining(SourceFile:0) > at j$.util.stream.c.c0(SourceFile:0) > at j$.util.stream.c.F0(Unknown Source:10) > at j$.util.stream.C0.v(Unknown Source:4) > at j$.util.stream.c.I0(SourceFile:0) > at j$.util.stream.m2.collect(SourceFile:0) > at org.joinmastodon.android.ui.CustomEmojiPopupKeyboard$SingleCategoryAdapter.(SourceFile:242) > at org.joinmastodon.android.ui.CustomEmojiPopupKeyboard.onCreateView(SourceFile:119) > at org.joinmastodon.android.ui.PopupKeyboard.ensureView(SourceFile:41) > at org.joinmastodon.android.ui.PopupKeyboard.getView(SourceFile:47) > at org.joinmastodon.android.ui.displayitems.EmojiReactionsStatusDisplayItem$Holder.onBind(SourceFile:184) > at org.joinmastodon.android.ui.displayitems.EmojiReactionsStatusDisplayItem$Holder.onBind(SourceFile:145) > at me.grishka.appkit.utils.BindableViewHolder.bind(SourceFile:33) > at org.joinmastodon.android.fragments.BaseStatusListFragment$DisplayItemsAdapter.onBindViewHolder(SourceFile:977) > at org.joinmastodon.android.fragments.BaseStatusListFragment$DisplayItemsAdapter.onBindViewHolder(SourceFile:961) > at me.grishka.appkit.utils.MergeRecyclerAdapter.onBindViewHolder(SourceFile:123) > at me.grishka.appkit.views.UsableRecyclerView$FooterRecyclerAdapter.onBindViewHolder(SourceFile:433) > at androidx.recyclerview.widget.RecyclerView$Adapter.onBindViewHolder(SourceFile:7256) > at androidx.recyclerview.widget.RecyclerView$Adapter.bindViewHolder(SourceFile:7339) > at androidx.recyclerview.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(SourceFile:6197) > at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(SourceFile:6463) > at androidx.recyclerview.widget.GapWorker.prefetchPositionWithDeadline(SourceFile:287) > at androidx.recyclerview.widget.GapWorker.flushTaskWithDeadline(SourceFile:344) > at androidx.recyclerview.widget.GapWorker.flushTasksWithDeadline(SourceFile:360) > at androidx.recyclerview.widget.GapWorker.prefetch(SourceFile:367) > at androidx.recyclerview.widget.GapWorker.run(SourceFile:398) > at android.os.Handler.handleCallback(Handler.java:958) > at android.os.Handler.dispatchMessage(Handler.java:99) > at android.os.Looper.loopOnce(Looper.java:230) > at android.os.Looper.loop(Looper.java:319) > at android.app.ActivityThread.main(ActivityThread.java:8893) > at java.lang.reflect.Method.invoke(Native Method) > at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:608) > at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103) > ```
Leah96xxx commented 10 months ago

Just got the same thing when opening a random profile after scrolling the federated timeline, only this was an instant crash after failing to load profile posts.

Click for log > ``` > 2.1.6+fork.110 (110) > 2024-01-11T12:18:26.358Z > > java.lang.OutOfMemoryError: Failed to allocate a 120 byte allocation with 1242432 free bytes and 1213KB until OOM, target footprint 536870912, growth limit 536870912; giving up on allocation because <1% of heap free after GC. > at java.lang.StringFactory.newStringFromBytes(Native Method) > at java.lang.StringLatin1.newString(StringLatin1.java:738) > at java.lang.StringBuilder.toString(StringBuilder.java:474) > at me.grishka.appkit.imageloader.requests.UrlImageLoaderRequest.(SourceFile:27) > at me.grishka.appkit.imageloader.requests.UrlImageLoaderRequest.(SourceFile:36) > at me.grishka.appkit.imageloader.requests.UrlImageLoaderRequest.(SourceFile:44) > at org.joinmastodon.android.ui.CustomEmojiPopupKeyboard$SingleCategoryAdapter.lambda$new$0(SourceFile:242) > at org.joinmastodon.android.ui.CustomEmojiPopupKeyboard$SingleCategoryAdapter.$r8$lambda$4MiXBTpf0wNyHQhD-Wq1Y-nOQpU(SourceFile:0) > at org.joinmastodon.android.ui.CustomEmojiPopupKeyboard$SingleCategoryAdapter$$ExternalSyntheticLambda0.apply(SourceFile:0) > at j$.util.stream.f2.accept(SourceFile:0) > at j$.util.a.forEachRemaining(SourceFile:0) > at j$.util.stream.c.c0(SourceFile:0) > at j$.util.stream.c.F0(Unknown Source:10) > at j$.util.stream.C0.v(Unknown Source:4) > at j$.util.stream.c.I0(SourceFile:0) > at j$.util.stream.m2.collect(SourceFile:0) > at org.joinmastodon.android.ui.CustomEmojiPopupKeyboard$SingleCategoryAdapter.(SourceFile:242) > at org.joinmastodon.android.ui.CustomEmojiPopupKeyboard.onCreateView(SourceFile:119) > at org.joinmastodon.android.ui.PopupKeyboard.ensureView(SourceFile:41) > at org.joinmastodon.android.ui.PopupKeyboard.getView(SourceFile:47) > at org.joinmastodon.android.ui.displayitems.EmojiReactionsStatusDisplayItem$Holder.onBind(SourceFile:184) > at org.joinmastodon.android.ui.displayitems.EmojiReactionsStatusDisplayItem$Holder.onBind(SourceFile:145) > at me.grishka.appkit.utils.BindableViewHolder.bind(SourceFile:33) > at org.joinmastodon.android.fragments.BaseStatusListFragment$DisplayItemsAdapter.onBindViewHolder(SourceFile:977) > at org.joinmastodon.android.fragments.BaseStatusListFragment$DisplayItemsAdapter.onBindViewHolder(SourceFile:961) > at me.grishka.appkit.views.UsableRecyclerView$FooterRecyclerAdapter.onBindViewHolder(SourceFile:433) > at androidx.recyclerview.widget.RecyclerView$Adapter.onBindViewHolder(SourceFile:7256) > at androidx.recyclerview.widget.RecyclerView$Adapter.bindViewHolder(SourceFile:7339) > at androidx.recyclerview.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(SourceFile:6197) > at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(SourceFile:6463) > at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(SourceFile:6303) > at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(SourceFile:6299) > at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next(SourceFile:2328) > at androidx.recyclerview.widget.GridLayoutManager.layoutChunk(SourceFile:571) > at androidx.recyclerview.widget.LinearLayoutManager.fill(SourceFile:1589) > at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(SourceFile:666) > at androidx.recyclerview.widget.GridLayoutManager.onLayoutChildren(SourceFile:169) > at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2(SourceFile:4300) > at androidx.recyclerview.widget.RecyclerView.dispatchLayout(SourceFile:4003) > at androidx.recyclerview.widget.RecyclerView.onLayout(SourceFile:4569) > at android.view.View.layout(View.java:25737) > at android.view.ViewGroup.layout(ViewGroup.java:6818) > at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332) > at android.widget.FrameLayout.onLayout(FrameLayout.java:270) > at android.view.View.layout(View.java:25737) > at android.view.ViewGroup.layout(ViewGroup.java:6818) > at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332) > at android.widget.FrameLayout.onLayout(FrameLayout.java:270) > at android.view.View.layout(View.java:25737) > at android.view.ViewGroup.layout(ViewGroup.java:6818) > at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1891) > at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1729) > at android.widget.LinearLayout.onLayout(LinearLayout.java:1638) > at android.view.View.layout(View.java:25737) > at android.view.ViewGroup.layout(ViewGroup.java:6818) > at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332) > at android.widget.FrameLayout.onLayout(FrameLayout.java:270) > at android.view.View.layout(View.java:25737) > at android.view.ViewGroup.layout(ViewGroup.java:6818) > at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332) > at android.widget.FrameLayout.onLayout(FrameLayout.java:270) > at android.view.View.layout(View.java:25737) > at android.view.ViewGroup.layout(ViewGroup.java:6818) > at androidx.recyclerview.widget.RecyclerView$LayoutManager.layoutDecoratedWithMargins(SourceFile:9880) > at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(SourceFile:1687) > at androidx.recyclerview.widget.LinearLayoutManager.fill(SourceFile:1589) > at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(SourceFile:666) > at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2(SourceFile:4300) > at androidx.recyclerview.widget.RecyclerView.dispatchLayout(SourceFile:4003) > at androidx.recyclerview.widget.RecyclerView.onLayout(SourceFile:4569) > at android.view.View.layout(View.java:25737) > at android.view.ViewGroup.layout(ViewGroup.java:6818) > at androidx.viewpager2.widget.ViewPager2.onLayout(SourceFile:523) > at android.view.View.layout(View.java:25737) > at android.view.ViewGroup.layout(ViewGroup.java:6818) > at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332) > at android.widget.FrameLayout.onLayout(FrameLayout.java:270) > at android.view.View.layout(View.java:25737) > at android.view.ViewGroup.layout(ViewGroup.java:6818) > at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1891) > at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1729) > at android.widget.LinearLayout.onLayout(LinearLayout.java:1638) > at android.view.View.layout(View.java:25737) > at android.view.ViewGroup.layout(ViewGroup.java:6818) > at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332) > at android.widget.FrameLayout.onLayout(FrameLayout.java:270) > at org.joinmastodon.android.ui.views.CustomScrollView.onLayout(SourceFile:1686) > at android.view.View.layout(View.java:25737) > at android.view.ViewGroup.layout(ViewGroup.java:6818) > at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332) > at android.widget.FrameLayout.onLayout(FrameLayout.java:270) > at android.view.View.layout(View.java:25737) > at android.view.ViewGroup.layout(ViewGroup.java:6818) > at androidx.swiperefreshlayout.widget.SwipeRefreshLayout.onLayout(SourceFile:671) > at android.view.View.layout(View.java:25737) > at android.view.ViewGroup.layout(ViewGroup.java:6818) > at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332) > at android.widget.FrameLayout.onLayout(FrameLayout.java:270) > at android.view.View.layout(View.java:25737) > at android.view.ViewGroup.layout(ViewGroup.java:6818) > at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332) > at android.widget.FrameLayout.onLayout(FrameLayout.java:270) > at android.view.View.layout(View.java:25737) > at android.view.ViewGroup.layout(ViewGroup.java:6818) > at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1891) > at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1729) > at android.widget.LinearLayout.onLayout(LinearLayout.java:1638) > at android.view.View.layout(View.java:25737) > at android.view.ViewGroup.layout(ViewGroup.java:6818) > at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332) > at android.widget.FrameLayout.onLayout(FrameLayout.java:270) > at android.view.View.layout(View.java:25737) > at android.view.ViewGroup.layout(ViewGroup.java:6818) > at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332) > at android.widget.FrameLayout.onLayout(FrameLayout.java:270) > at android.view.View.layout(View.java:25737) > at android.view.ViewGroup.layout(ViewGroup.java:6818) > at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332) > at android.widget.FrameLayout.onLayout(FrameLayout.java:270) > at android.view.View.layout(View.java:25737) > at android.view.ViewGroup.layout(ViewGroup.java:6818) > at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332) > at android.widget.FrameLayout.onLayout(FrameLayout.java:270) > at android.view.View.layout(View.java:25737) > at android.view.ViewGroup.layout(ViewGroup.java:6818) > at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332) > at android.widget.FrameLayout.onLayout(FrameLayout.java:270) > at com.android.internal.policy.DecorView.onLayout(DecorView.java:1075) > at android.view.View.layout(View.java:25737) > at android.view.ViewGroup.layout(ViewGroup.java:6818) > at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:5193) > at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:4466) > at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:3239) > at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:11197) > at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1650) > at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1659) > at android.view.Choreographer.doCallbacks(Choreographer.java:1129) > at android.view.Choreographer.doFrame(Choreographer.java:1055) > at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1622) > at android.os.Handler.handleCallback(Handler.java:958) > at android.os.Handler.dispatchMessage(Handler.java:99) > at android.os.Looper.loopOnce(Looper.java:230) > at android.os.Looper.loop(Looper.java:319) > at android.app.ActivityThread.main(ActivityThread.java:8893) > at java.lang.reflect.Method.invoke(Native Method) > at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:608) > at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103) > ```