1

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

这些是数据项:

@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。对于这种行为的原因以及是否可以更改的任何想法,我将不胜感激。

4

2 回答 2

0

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

使用 Jetpack Compos 的分页列表视图

于 2021-11-17T19:45:45.827 回答
0

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

于 2021-12-06T21:49:15.210 回答