question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

ListView leaks memory and doesn't clean up (Android)

See original GitHub issue

Hi there, I’m using RN 0.41.2 on an Android device (not emulator). I’ve created a really simple ListView component. As I scroll down this list, the memory used by the app increases linearly. If I background the app, this memory doesn’t get cleaned up at all.

While the code below is simple, you can imagine how out-of-hand this gets on a ListView that renders more-detailed rows (including Image and TouchableOpacity). The problem is that the app I’m building is a music streaming app. If I scroll through ~3 pages of tracks, it bring the app’s total consumption up to ~150MB of ram (from an initial boot of 90MB), which makes it the #1 candidate for Android to garbage collect if another app takes the foreground and requires more memory (eg, you want to browse Chrome while listening to the music app in the background). Without the ListView, my app uses up ~55MB – a number similar to the one generated by the simple component below.

I’ve tried this with the new/experimental FlatList component, and I get similar - if not worse - results as far as memory consumption. This is the main thing holding me back from rolling out my React Native version to production (on an app with 500,000+ installs).

import React, { Component } from 'react';
import {
  AppRegistry,
  Text,
  ListView
} from 'react-native';

var data = []
for (var ii = 0; ii < 1000; ii++) {
    data.push('row - ' + ii)
}

export default class AwesomeProject extends Component {
  constructor() {
    super();
    const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
    this.state = {
      dataSource: ds.cloneWithRows(data),
    };
  }

  render() {
    return (
      <ListView
        dataSource={this.state.dataSource}
        initialListSize={50}
        pageSize={50}
        renderRow={(rowData) => <Text>{rowData}</Text>}
      />
    );
  }
}

AppRegistry.registerComponent('AwesomeProject', () => AwesomeProject);

Screenshots below created using “adb shell dumpsys meminfo -a com.awesomeproject”

snapshot1 snapshot2 snapshot3 snapshot4

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Comments:30 (14 by maintainers)

github_iconTop GitHub Comments

2reactions
sahrenscommented, Mar 2, 2017

Yeah, 400MB is still a little high - what device are you running on? The heap and cache sizes will vary depending on the device memory. The view count is much more reasonable, but also a bit high. You can try dialing down the windowSize too. The default is 21 which is actually quite large.

But note that the live memory number is going to be much higher than the background number. That 359mb includes GPU texture buffers and other caches that should be cleared when the app is backgrounded. It also might take a while for the JS Garbage collector to trigger a cleanup and release the memory back to the operating system.

Memory is a very complex issue. Have you tried doing similar analysis with other apps? What happens if you scroll through the same amount of content in the other apps, like Twitter?

2reactions
brentvatnecommented, Feb 22, 2017

Hello! What you are describing here is (sadly) the intended behavior of react-native’s ListView component on iOS and Android – it does not recycle views or unmount anything that goes out of view, with the exception of images if you use removeClippedSubviews. I see you looked into FlatList @jasongrishkoff – that should help with this problem because it uses windowing – only the contents you can currently see and some buffer around the contents are actually rendered.

Read more comments on GitHub >

github_iconTop Results From Across the Web

java - Listview memory leak - Stack Overflow
I have a simple list view with adapter. I create 10+ listviewitems dynamically. Then I scroll up and down again and again and...
Read more >
Preventing and detecting memory leaks in Android apps
Memory leaks can cause your Android app to crash, causing frustration and lower usage. Learn how to fix them in this guide.
Read more >
Memory/GREF Leak on XForms.Android When Using ...
The memory leak issue can be fixed by setting caching strategy in the list view. By default, the caching strategy is set as...
Read more >
Fix your Android Memory Leaks in Fragments - Procore
A Github project has been created to showcase the memory leaks with the fragment's view, as well as the leak happening with a...
Read more >
Minute of Pain #2. Leaks - Michael Spitsin - Medium
Unfortunately, we used version 3.2 of Android Annotations lib and their 'not cleaning views in fragments' fix came out only with version 4.0....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found