In my app there's a LazyColumn
that contains nested LazyRows
. I have a memory issue - when there are 30-40 rows and about 10-20 elements per row in the grid, it's possible to reach Out-of-Memory (OOM) by simply scrolling the list vertically up and down about 20 times. An item is a Card
with some Boxes
and texts. It seems that the resulting composable for each of the items is stored, even when the item is out of composition.
Here is a sample that demonstrates this. It shows a simple grid of 600 elements (they are just Text
) and on my emulator gets to a memory usage of about 200 MB. (I use Android TV emulator with landscape, 120 elements are visible at once).
MainActivity.kt
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
LazyColumnTestTheme {
// A surface container using the 'background' color from the theme
Surface(color = MaterialTheme.colors.background) {
runTest()
}
}
}
}
}
@Composable
fun runTest() {
var itemsState: MutableState<List<TestDataBlock>> = remember {
mutableStateOf(listOf())
}
LaunchedEffect(Unit) {
delay(1000)
itemsState.value = MutableList<TestDataBlock>(30) { rowIndex ->
val id = rowIndex
TestDataBlock(id = id.toString(), data = 1)
}
}
List(dataItems = itemsState.value)
}
@Preview
@Composable
fun List(
dataItems: List<TestDataBlock> = listOf(TestDataBlock("1",1), TestDataBlock("2",2))
) {
LazyColumn(
modifier = Modifier
.fillMaxSize()
) {
itemsIndexed(items = dataItems,
key = { _, item ->
item.id
}
) { _, rowItem ->
drawElement(rowItem)
}
}
}
@Composable
fun drawElement(rowItem: TestDataBlock) {
Text(text = "${rowItem.id}")
LazyRow() {
itemsIndexed(items = rowItem.testDataItems,
key = { _, item ->
item.id
}
) { _, item ->
Text(text = "${item.id }", color = Color.Black, modifier = Modifier.width(100.dp))
}
}
}
TestDataBlock.kt
@Immutable
data class TestDataBlock(
val id: String,
val data: Int,
) {
val testDataItems: List<TestDataItem> = (0..20).toList().map{ TestDataItem(it.toString()) }
}
TestDataItem.kt
@Immutable
data class TestDataItem(
val id: String
)