Wie repariere ich Speicherleck, das durch ViewModel -Delegate verursacht wird?Android

Forum für diejenigen, die für Android programmieren
Anonymous
 Wie repariere ich Speicherleck, das durch ViewModel -Delegate verursacht wird?

Post by Anonymous »

Leckkanar -Protokolle zeigen, dass nach ViewModel.onclear () das pagemodelpagingDataflow keinen Speicher veröffentlicht. hiltnavgraphviewModels (R.Id.DocpagelistFagment) . Ich habe jedoch einen anderen Aktivitätsbildschirm, der keine Fragmente verwendet und von ViewModels () verwendet. Das Speicherleck von pager.flow.cachedin tritt ebenfalls auf. So beheben Sie es?

Code: Select all

@HiltViewModel
class DocPageListViewModel @Inject constructor(
private val docPageDao: DocPageDao,
) : BaseViewModel() {

val pageModelPagingDataFlow = Pager(PagingConfig(pageSize = 10, initialLoadSize = 20)) {
docPageDao.getPagingSource()
}.flow.cachedIn(viewModelScope)

}
< /code>
@Dao
interface DocPageDao {

@Query("""
SELECT rowid, lid, `key`
FROM page_table_fts4
ORDER BY `key`
""")
fun getPagingSource(): PagingSource

}
< /code>
@AndroidEntryPoint
class DocPageListFragment : BaseFragment(
R.layout.fragment_doc_page_list
) {

override val viewModel: DocPageListViewModel by activityViewModels()

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

val listAdapter = DocPageListPagingDataAdapter(requireContext(), this)
binding.recyclerView.adapter = listAdapter

viewCollectLatestWhenStarted(viewModel.pageModelPagingDataFlow) { pagingData ->
listAdapter.submitData(pagingData)
}
}
}
< /code>
fun  Fragment.viewCollectLatestWhenStarted(flow: Flow, block: suspend (T) -> Unit) {
viewCollectLatestWhen(Lifecycle.State.STARTED, flow, block)
}

fun  Fragment.viewCollectLatestWhen(state: Lifecycle.State, flow: Flow, block: suspend (T) ->  Unit) {
viewLifecycleOwner.lifecycleScope.launch {
repeatOnLifecycle(state) {
flow.collectLatest {
block(it)
}
}
}
}
< /code>
 ┬───
│ GC Root: System class
│
├─ android.provider.FontsContract class
│    Leaking: NO (App↓ is not leaking and a class is never leaking)
│    ↓ static FontsContract.sContext
├─ com.example.name.App instance
│    Leaking: NO (Application is a singleton)
│    mBase instance of android.app.ContextImpl
│    ↓ Hilt_App.componentManager
│               ~~~~~~~~~~~~~~~~
├─ dagger.hilt.android.internal.managers.ApplicationComponentManager instance
│    Leaking: UNKNOWN
│    Retaining 40 B in 3 objects
│    ↓ ApplicationComponentManager.component
│                                  ~~~~~~~~~
├─ com.example.name.DaggerApp_HiltComponents_SingletonC$SingletonCImpl instance
│    Leaking: UNKNOWN
│    Retaining 25,5 kB in 999 objects
│    ↓ DaggerApp_HiltComponents_SingletonC$SingletonCImpl.provideDatabaseProvider6
│                                                         ~~~~~~~~~~~~~~~~~~~~~~~~
├─ dagger.internal.DoubleCheck instance
│    Leaking: UNKNOWN
│    Retaining 16 B in 1 objects
│    ↓ DoubleCheck.instance
│                  ~~~~~~~~
├─ com.example.name.db.docs.DocsDatabase_Impl instance
│    Leaking: UNKNOWN
│    Retaining 14,9 kB in 540 objects
│    ↓ RoomDatabase.transactionContext
│                   ~~~~~~~~~~~~~~~~~~
├─ kotlin.coroutines.CombinedContext instance
│    Leaking: UNKNOWN
│    Retaining 32 B in 2 objects
│    ↓ CombinedContext.left
│                      ~~~~
├─ kotlinx.coroutines.SupervisorJobImpl instance
│    Leaking: UNKNOWN
│    Retaining 105 B in 5 objects
│    ↓ JobSupport._state$volatile
│                 ~~~~~~~~~~~~~~~
├─ kotlinx.coroutines.NodeList instance
│    Leaking: UNKNOWN
│    Retaining 88 B in 4 objects
│    ↓ LockFreeLinkedListNode._prev$volatile
│                             ~~~~~~~~~~~~~~
├─ kotlinx.coroutines.ChildHandleNode instance
│    Leaking: UNKNOWN
│    Retaining 28 B in 1 objects
│    ↓ ChildHandleNode.childJob
│                      ~~~~~~~~
├─ kotlinx.coroutines.StandaloneCoroutine instance
│    Leaking: UNKNOWN
│    Retaining 20 B in 1 objects
│    ↓ JobSupport._state$volatile
│                 ~~~~~~~~~~~~~~~
├─ kotlinx.coroutines.ChildContinuation instance
│    Leaking: UNKNOWN
│    Retaining 28 B in 1 objects
│    ↓ ChildContinuation.child
│                        ~~~~~
├─ kotlinx.coroutines.CancellableContinuationImpl instance
│    Leaking: UNKNOWN
│    Retaining 10,5 kB in 355 objects
│    ↓ CancellableContinuationImpl.delegate
│                                  ~~~~~~~~
├─ kotlinx.coroutines.internal.DispatchedContinuation instance
│    Leaking: UNKNOWN
│    Retaining 10,4 kB in 354 objects
│    ↓ DispatchedContinuation.continuation
│                             ~~~~~~~~~~~~
├─ kotlinx.coroutines.flow.StateFlowImpl$collect$1 instance
│    Leaking: UNKNOWN
│    Retaining 10,4 kB in 353 objects
│    Anonymous subclass of kotlin.coroutines.jvm.internal.ContinuationImpl
│    ↓ StateFlowImpl$collect$1.L$1
│                              ~~~
├─ androidx.room.TriggerBasedInvalidationTracker$createFlow$1$2 instance
│    Leaking: UNKNOWN
│    Retaining 37 B in 2 objects
│    Anonymous class implementing kotlinx.coroutines.flow.FlowCollector
│    ↓ TriggerBasedInvalidationTracker$createFlow$1$2.$$this$flow
│                                                     ~~~~~~~~~~~
├─ kotlinx.coroutines.flow.internal.SafeCollector instance
│    Leaking: UNKNOWN
│    Retaining 52 B in 2 objects
│    ↓ SafeCollector.collector
│                    ~~~~~~~~~
├─ androidx.room.paging.CommonLimitOffsetImpl$load$2$1 instance
│    Leaking: UNKNOWN
│    Retaining 12 B in 1 objects
│    Anonymous class implementing kotlinx.coroutines.flow.FlowCollector
│    ↓ CommonLimitOffsetImpl$load$2$1.this$0
│                                     ~~~~~~
├─ androidx.room.paging.CommonLimitOffsetImpl instance
│    Leaking: UNKNOWN
│    Retaining 10,0 kB in 339 objects
│    ↓ CommonLimitOffsetImpl.pagingSource
│                            ~~~~~~~~~~~~
├─ com.example.name.db.docs.dao.DocPageDao_Impl$3 instance
│    Leaking:  UNKNOWN
│    Retaining 9,8 kB in 331 objects
│    Anonymous subclass of androidx.room.paging.LimitOffsetPagingSource
│    ↓ PagingSource.invalidateCallbackTracker
│                   ~~~~~~~~~~~~~~~~~~~~~~~~~
├─ androidx.paging.InvalidateCallbackTracker instance
│    Leaking: UNKNOWN
│    Retaining 9,8 kB in 330 objects
│    ↓ InvalidateCallbackTracker.callbacks
│                                ~~~~~~~~~
├─ java.util.ArrayList instance
│    Leaking: UNKNOWN
│    Retaining 9,7 kB in 327 objects
│    ↓ ArrayList[1]
│               ~~~
├─ androidx.paging.PageFetcher$generateNewPagingSource$3 instance
│    Leaking: UNKNOWN
│    Retaining 9,7 kB in 324 objects
│    Anonymous subclass of kotlin.jvm.internal.FunctionReferenceImpl
│    ↓ CallableReference.receiver
│                        ~~~~~~~~
├─ androidx.paging.PageFetcher instance
│    Leaking: UNKNOWN
│    Retaining 9,6 kB in 323 objects
│    ↓ PageFetcher.pagingSourceFactory
│                  ~~~~~~~~~~~~~~~~~~~
├─ androidx.paging.Pager$flow$2 instance
│    Leaking: UNKNOWN
│    Retaining 9,2 kB in 301 objects
│    Anonymous subclass of kotlin.coroutines.jvm.internal.SuspendLambda
│    ↓ Pager$flow$2.$pagingSourceFactory
│                   ~~~~~~~~~~~~~~~~~~~~
├─ com.example.name.screens.docs.DocPageListViewModel$$ExternalSyntheticLambda0 instance
│    Leaking: UNKNOWN
│    Retaining 9,2 kB in 300 objects
│    ↓ DocPageListViewModel$$ExternalSyntheticLambda0.f$0
│                                                     ~~~
╰→ com.example.name.screens.docs.DocPageListViewModel instance
​     Leaking: YES (ObjectWatcher was watching this because com.example.name.screens.docs.DocPageListViewModel
​     received ViewModel#onCleared() callback)
​     Retaining 9,2 kB in 299 objects
​     key = 960c859b-f116-4150-842c-39fc5e2fc4d1
​     watchDurationMillis = 12664
​     retainedDurationMillis = 7664

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post