外部灵性lambda1泄漏金丝雀

发布于 2025-01-29 18:21:32 字数 4653 浏览 1 评论 0 原文

我正在使用LeakCanary来检测正在处理的应用程序中的泄漏。我不知道这个来自哪里。外部对lambda1可能是什么?我首先使用绑定,因此决定将其删除,因为SwipereFreshlayout泄漏了。看起来像是删除了绑定和旧学校的工作,但是现在我遇到了一个我不了解的新错误。帮助?谢谢

┬───
│ GC Root: Input or output parameters in native code
│
├─ dalvik.system.PathClassLoader instance
│    Leaking: NO (InternalLeakCanary↓ is not leaking and A ClassLoader is never
│    leaking)
│    ↓ ClassLoader.runtimeInternalObjects
├─ java.lang.Object[] array
│    Leaking: NO (InternalLeakCanary↓ is not leaking)
│    ↓ Object[36]
├─ leakcanary.internal.InternalLeakCanary class
│    Leaking: NO (MainActivity↓ is not leaking and a class is never leaking)
│    ↓ static InternalLeakCanary.resumedActivity
com.app.MainActivity instance
│    Leaking: NO (Activity#mDestroyed is false)
│    mApplication instance of com.app.Application
│    mBase instance of androidx.appcompat.view.ContextThemeWrapper
│    ↓ MainActivity.userViewModel$delegate
│                   ~~~~~~~~~~~~~~~~~~~~~~
├─ kotlin.SynchronizedLazyImpl instance
│    Leaking: UNKNOWN
│    Retaining 20 B in 1 objects
│    ↓ SynchronizedLazyImpl._value
│                           ~~~~~~
├─ com.app.user.UserViewModel instance
│    Leaking: UNKNOWN
│    Retaining 4.4 kB in 103 objects
│    ↓ UserViewModel._userId
│                    ~~~~~~~
├─ androidx.lifecycle.MutableLiveData instance
│    Leaking: UNKNOWN
│    Retaining 427 B in 19 objects
│    ↓ LiveData.mObservers
│               ~~~~~~~~~~
├─ androidx.arch.core.internal.SafeIterableMap instance
│    Leaking: UNKNOWN
│    Retaining 368 B in 16 objects
│    ↓ SafeIterableMap[key()]
│                     ~~~~~~~
├─ com.app.today.habitday.
│  HabitDayFragment$$ExternalSyntheticLambda1 instance
│    Leaking: UNKNOWN
│    Retaining 12 B in 1 objects
│    ↓ HabitDayFragment$$ExternalSyntheticLambda1.f$0
│                                                 ~~~
╰→ com.app.today.habitday.HabitDayFragment instance
​     Leaking: YES (ObjectWatcher was watching this because com.app.today.habitday.HabitDayFragment received Fragment#onDestroy()
​     callback and Fragment#mFragmentManager is null)
​     Retaining 48.7 kB in 805 objects
​     key = 31c4bca9-d5f5-478d-b9cd-e4f826d3764c
​     watchDurationMillis = 5699
​     retainedDurationMillis = 699

METADATA

Build.VERSION.SDK_INT: 31
Build.MANUFACTURER: samsung
LeakCanary version: 2.8.1
App process name: com.app
Stats: LruCache[maxSize=3000,hits=145238,misses=327470,hitRate=30%]
RandomAccess[bytes=24498778,reads=327470,travel=129136265851,range=54226345,size
=65429917]
Analysis duration: 22458 ms

,我想我已经关注了所有最佳实践带有视图模型和观察。

class UserViewModel(private val repository: repository,
                    private val chatRepository: ChatRepository,
                    private val crashlyticsHelper: CrashlyticsHelper,
                    private val systemMemoryHelper: SystemMemoryHelper) : ViewModel(), EventListener {


    ...
    private var _userId = MutableLiveData<String>()
    val userId: LiveData<String> = _userId
    ...

    override fun onCleared() {
        super.onCleared()
        // Clearing listeners
        chatRepository.unregisterListener(this)
    }

class HabitDayFragment: Fragment(R.layout.fragment_habit_day) {
    private val repository: Repository by inject()
    private val analyticsHelper: AnalyticsHelper by inject()
    private val userViewModel: UserViewModel by inject()

    ...
    companion object {
        fun instance(localDate: LocalDate): HabitDayFragment {
            val data = Bundle()
            data.putString(DATE_BUNDLE_STRING, DateUtils.localDateToString(localDate))
            return HabitDayFragment().apply {
                arguments = data
            }
        }
    }
    ...

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        habitDayViewModel = ViewModelProvider(this,    HabitDayViewModelFactory(repository)).get(HabitDayViewModel::class.java)
        habitDayViewModel?.updateDate(localDate)
        // Using lifecycleOwner here
        userViewModel.userId.observe(viewLifecycleOwner, Observer {
            habitDayViewModel?.setUserId(it)
        })

        ...
        // Also using lifecycle owner here, and repeat on lifecycle.
        viewLifecycleOwner.lifecycleScope.launch {
            viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
                habitDayViewModel?.uiState?.distinctUntilChanged
    ....

I'm using LeakCanary to detect leaks in the app I'm working on. And I have no idea where this one comes from. What might ExternalSyntheticLambda1 refer to? I used binding first, and I decided to remove that, since SwipeRefreshLayout leaked. It looks like removing the binding and going old school worked, however now I get a new error that I don't understand. Help? Thanks

┬───
│ GC Root: Input or output parameters in native code
│
├─ dalvik.system.PathClassLoader instance
│    Leaking: NO (InternalLeakCanary↓ is not leaking and A ClassLoader is never
│    leaking)
│    ↓ ClassLoader.runtimeInternalObjects
├─ java.lang.Object[] array
│    Leaking: NO (InternalLeakCanary↓ is not leaking)
│    ↓ Object[36]
├─ leakcanary.internal.InternalLeakCanary class
│    Leaking: NO (MainActivity↓ is not leaking and a class is never leaking)
│    ↓ static InternalLeakCanary.resumedActivity
com.app.MainActivity instance
│    Leaking: NO (Activity#mDestroyed is false)
│    mApplication instance of com.app.Application
│    mBase instance of androidx.appcompat.view.ContextThemeWrapper
│    ↓ MainActivity.userViewModel$delegate
│                   ~~~~~~~~~~~~~~~~~~~~~~
├─ kotlin.SynchronizedLazyImpl instance
│    Leaking: UNKNOWN
│    Retaining 20 B in 1 objects
│    ↓ SynchronizedLazyImpl._value
│                           ~~~~~~
├─ com.app.user.UserViewModel instance
│    Leaking: UNKNOWN
│    Retaining 4.4 kB in 103 objects
│    ↓ UserViewModel._userId
│                    ~~~~~~~
├─ androidx.lifecycle.MutableLiveData instance
│    Leaking: UNKNOWN
│    Retaining 427 B in 19 objects
│    ↓ LiveData.mObservers
│               ~~~~~~~~~~
├─ androidx.arch.core.internal.SafeIterableMap instance
│    Leaking: UNKNOWN
│    Retaining 368 B in 16 objects
│    ↓ SafeIterableMap[key()]
│                     ~~~~~~~
├─ com.app.today.habitday.
│  HabitDayFragment$ExternalSyntheticLambda1 instance
│    Leaking: UNKNOWN
│    Retaining 12 B in 1 objects
│    ↓ HabitDayFragment$ExternalSyntheticLambda1.f$0
│                                                 ~~~
╰→ com.app.today.habitday.HabitDayFragment instance
​     Leaking: YES (ObjectWatcher was watching this because com.app.today.habitday.HabitDayFragment received Fragment#onDestroy()
​     callback and Fragment#mFragmentManager is null)
​     Retaining 48.7 kB in 805 objects
​     key = 31c4bca9-d5f5-478d-b9cd-e4f826d3764c
​     watchDurationMillis = 5699
​     retainedDurationMillis = 699

METADATA

Build.VERSION.SDK_INT: 31
Build.MANUFACTURER: samsung
LeakCanary version: 2.8.1
App process name: com.app
Stats: LruCache[maxSize=3000,hits=145238,misses=327470,hitRate=30%]
RandomAccess[bytes=24498778,reads=327470,travel=129136265851,range=54226345,size
=65429917]
Analysis duration: 22458 ms

I think I'm already following all the best practices with view models and observing.

class UserViewModel(private val repository: repository,
                    private val chatRepository: ChatRepository,
                    private val crashlyticsHelper: CrashlyticsHelper,
                    private val systemMemoryHelper: SystemMemoryHelper) : ViewModel(), EventListener {


    ...
    private var _userId = MutableLiveData<String>()
    val userId: LiveData<String> = _userId
    ...

    override fun onCleared() {
        super.onCleared()
        // Clearing listeners
        chatRepository.unregisterListener(this)
    }

class HabitDayFragment: Fragment(R.layout.fragment_habit_day) {
    private val repository: Repository by inject()
    private val analyticsHelper: AnalyticsHelper by inject()
    private val userViewModel: UserViewModel by inject()

    ...
    companion object {
        fun instance(localDate: LocalDate): HabitDayFragment {
            val data = Bundle()
            data.putString(DATE_BUNDLE_STRING, DateUtils.localDateToString(localDate))
            return HabitDayFragment().apply {
                arguments = data
            }
        }
    }
    ...

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        habitDayViewModel = ViewModelProvider(this,    HabitDayViewModelFactory(repository)).get(HabitDayViewModel::class.java)
        habitDayViewModel?.updateDate(localDate)
        // Using lifecycleOwner here
        userViewModel.userId.observe(viewLifecycleOwner, Observer {
            habitDayViewModel?.setUserId(it)
        })

        ...
        // Also using lifecycle owner here, and repeat on lifecycle.
        viewLifecycleOwner.lifecycleScope.launch {
            viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
                habitDayViewModel?.uiState?.distinctUntilChanged
    ....

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

情场扛把子 2025-02-05 18:21:32

事实证明,这是 viewPager2 ,它通过不调用 ondestroyview 而导致问题。通过转到良好的OL' ViewPager V1来修复它。

更多信息: fragment lifecylce行为

Turns out, it was ViewPager2 that was causing the issues by not calling onDestroyView. Fixed it by going to the good ol' ViewPager v1.

More here: Fragment lifecylce behaviour using ViewPager2 and FragmentStateAdapter

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文