Почему сборщик мусора никогда не работает с маркерами React Native Map? - PullRequest
0 голосов
/ 08 октября 2019

My React Native приложение получает эту ошибку после некоторого времени использования:

java.lang.OutOfMemoryError: 
  at dalvik.system.VMRuntime.newNonMovableArray (Native Method)
  at android.graphics.Bitmap.nativeCreate (Native Method)
  at android.graphics.Bitmap.createBitmap (Bitmap.java:975)
  at android.graphics.Bitmap.createBitmap (Bitmap.java:946)
  at android.graphics.Bitmap.createBitmap (Bitmap.java:913)
  at com.airbnb.android.react.maps.AirMapMarker.createDrawable (AirMapMarker.java:538)

У меня есть веб-розетка, которая прослушивает обновления местоположения многих пользователей. сохраняйте список координат и каждые N секунд я обновляю состояние новыми позициями маркера.

Я наблюдал за памятью в Android-студии Profiler и вижу, что создано много объектов AirMapMarker, но ни один из них не освобожден и выделена памятьпродолжает увеличиваться.

Это соответствующий код:

function renderMarker(marker, index) {


    return <MapMarker
        coordinate={marker.coordinate}
        title={marker.title}
        description={marker.description}
        key={marker.key}
    >
        <Text style={styles.labels}>{marker.title}</Text>
        <Image
            source={dotImage}
            style={{ height: 32, width: 32 }}
        />

    </MapMarker>
}

class HomeWithoutSocket extends Component {

    newmarkers = []
...

    updateMarkers() {
        if (!this.state.isMounted) {
            return;
        };


        this.setState({ markers: this.newmarkers });
        this.newmarkers = []

    }

    componentDidMount() {
        this.socketEvents();
        setTimeout(this.updateMarkers.bind(this), 5000);
        this.updateMarkersInterval = setInterval(this.updateMarkers.bind(this), 30000);
        ...
        this.setState({ isMounted: true });
    }

    componentWillUnmount() {

        clearInterval(this.updateMarkersInterval);
        this.setState({ isMounted: false });
    }

    socketEvents() {
        ...
        this.props.socket.on('taxi position', (data) => {

            if (!this.state.isMounted) {
                return;
            };
            this.newmarkers.push({ title: data.id, coordinate: { latitude: parseFloat(data.lat), longitude: parseFloat(data.lng) }, description: "" });
        });
    }

    render() {
        return (
            <View style={styles.container}>


                <MapView
                    ref={MapView => (this.MapView = MapView)}
                    provider={this.props.provides}
                    style={styles.map}
                    scrollEnabled={true}
                    zoomEnabled={true}
                    pitchEnabled={true}
                    // mapType={this.mapType}
                    rotateEnabled={true}
                    initialRegion={this.state.region}
                    customMapStyle={this.mapStyle}
                >


                    {this.state.markers.map((marker, index) => (

                        renderMarker(marker, index)
                    ))}

                    <UrlTile
                        urlTemplate="http://xxx.xxx.xx.xxx/hot2/{z}/{x}/{y}.png?"
                        maximumZ={19}
                    />
                </MapView>
            </View >
        );
    }

...

У маркеров все еще есть ссылка, поэтому сборщик мусора никогда не удаляет их из памяти?

...