LazyColumn 项目从列表中删除后保留在内存中

Posted

技术标签:

【中文标题】LazyColumn 项目从列表中删除后保留在内存中【英文标题】:LazyColumn items staying in memory after they are removed from the list 【发布时间】:2021-12-28 18:08:43 【问题描述】:

我发现我的应用程序使用了异常大量的内存。有一个LazyColumn 定期更新数据。我发现在这些更新之后,内存中的列表项实例的数量会随着时间的推移而增加,并且一次增长到明显大于列表中的最大项目数量。 我做了一个小样本来说明问题here。

这些是数据项:

@Immutable
data class TestDataBlock(
    val id: String,
    val data: Int
)

LazyColumn 看起来像这样。

@Composable
fun List(dataItems: List<TestDataBlock>) 
    LazyColumn(
        modifier = Modifier.fillMaxSize()
    ) 
        itemsIndexed(items = dataItems,
            key =  index, item ->
                item.id
            
        )  rowIndex, rowItem ->
            drawElement(rowItem)
        
    


@Composable
fun drawElement(rowItem: TestDataBlock) 
    Text(text = "$rowItem.data")

在这个示例中,我在LazyColumn 中设置了两部分数据,然后我清理了它。

@Composable
fun runTest() 
    var itemsState: MutableState<List<TestDataBlock>> = remember 
        mutableStateOf(listOf())
    

    LaunchedEffect(Unit) 
        delay(1000)
        itemsState.value = MutableList<TestDataBlock>(30)  rowIndex ->            
            TestDataBlock(id = rowIndex.toString(), data = 1)
        
        delay(1000)
        itemsState.value = MutableList<TestDataBlock>(30)  rowIndex ->            
            TestDataBlock(id = rowIndex.toString(), data = 2)
        
        delay(1000)
        itemsState.value = listOf()
    

    List(dataItems = itemsState.value)

我希望没有在内存中引用的项目示例(在分析器中可见),但不幸的是,最后一组数据仍在内存中,从 Compose 的某处引用。 在项目包含LazyRows 和图像的真实应用程序中,这样的多次更新会导致内存阻塞,并可能导致 OOM。 项目类是不可变的 (@Immutable),并且所有项目都有唯一的 ID。 如有任何关于此行为原因的想法以及是否可以更改,我将不胜感激。

【问题讨论】:

欢迎使用 ***。请在您的问题中添加一些主要的 Compose 代码,而不是添加存储库链接。 【参考方案1】:

您正在从 MutableList 而不是 Flow 中检索您的值。一个可变列表重新定义所有项目,而流将只检索可见的项目以及在第一个可见项目之前或最后一个可见项目之后的更多项目。您应该使用带有 Flow 的分页库来填充您的 LazyList。下面是一篇关于使用 Compose 和 LazyColum 进行分页的文章:

List view with Pagination using Jetpack Compos

【讨论】:

感谢您的回答!问题是,在这个例子中,我清理了可变列表,LazyColumn 也被清理了,并且项目仍在内存中: itemsState.value = listOf() 在实际应用中,我使用 Flow 将数据填充到 LazyColumn 中。跨度> 【参考方案2】:

我已经为 Google 填写了一个错误,他们已经复制了该错误:https://issuetracker.google.com/issues/207946467

【讨论】:

以上是关于LazyColumn 项目从列表中删除后保留在内存中的主要内容,如果未能解决你的问题,请参考以下文章

LazyColumn 中每个项目的状态提升

Compose:LazyColumn 在单个项目更新时重新组合所有项目

从父级删除后保留的子视图控制器

在jetpack compose LazyColumn中获取最后一个可见的项目索引

从列表框中删除项目(MS Access VBA)

LazyColumn 项目互斥