从屏幕中删除元素后反应Native伪泄漏内存(ios)

Asp*_*ina 14 memory-leaks react-native

我正在经历一些生产中的内存崩溃.试图找出问题,我可以制作一个小应用程序来重现问题.

import React from 'react';                                                                                                                                                                             
import { StyleSheet, Text, View, TouchableOpacity } from 'react-native';                                                                                                                               

export default class App extends React.Component {                                                                                                                                                     
  constructor(props) {                                                                                                                                                                                 
    super(props);                                                                                                                                                                                      
    this.state = {                                                                                                                                                                                     
      count: 0,                                                                                                                                                                                        
    };                                                                                                                                                                                                 
  }                                                                                                                                                                                                    

  render() {                                                                                                                                                                                           
    const { count } = this.state;                                                                                                                                                                      
    const extraContent = new Array(200 * count).fill().map((_, index) => (                                                                                                                             
      <View key={index}><Text>Line {index}</Text></View>                                                                                                                                               
    ));                                                                                                                                                                                                

    return (                                                                                                                                                                                           
      <View style={styles.container}>                                                                                                                                                                  
        <View style={styles.actions}>                                                                                                                                                                  
          <TouchableOpacity onPress={() => this.setState({ count: count + 1})}>                                                                                                                        
            <View style={styles.button}>                                                                                                                                                               
              <Text style={styles.buttonText}>Add</Text>                                                                                                                                               
            </View>                                                                                                                                                                                    
          </TouchableOpacity>                                                                                                                                                                          
          <TouchableOpacity onPress={() => count > 0 && this.setState({ count: count - 1})}>                                                                                                           
            <View style={styles.button}>                                                                                                                                                         
              <Text style={styles.buttonText}>Remove</Text>                                                                                                                                            
            </View>                                                                                                                                                                                    
          </TouchableOpacity>                                                                                                                                                                          
        </View>                                                                                                                                                                                        
        <View>                                                                                                                                                                                         
          <Text>Current count: {count}</Text>                                                                                                                                                          
          <View>{extraContent}</View>                                                                                                                                                                  
        </View>                                                                                                                                                                                        
      </View>                                                                                                                                                                                          
    );                                                                                                                                                                                                 
  }                                                                                                                                                                                                    
}                                                                                                                                                                                                      

const styles = StyleSheet.create({                                                                                                                                                                     
  container: {                                                                                                                                                                                         
    flex: 1,                                                                                                                                                                                           
    marginTop: 50,                                                                                                                                                                                     
    width: '100%',                                                                                                                                                                                     
  },                                                                                                                                                                                                   
  actions: {                                                                                                                                                                                           
    flexDirection: 'row',                                                                                                                                                                              
    alignItems: 'center',                                                                                                                                                                              
    justifyContent: 'space-around',                                                                                                                                                                    
  },                                                                                                                                                                                                   
  buttonText: {                                                                                                                                                                                        
    color: '#ffffff',                                                                                                                                                                                  
  },                                                                                                                                                                                                   
  button: {                                                                                                                                                                                            
    alignItems: 'center',                                                                                                                                                                              
    justifyContent: 'center',                                                                                                                                                                          
    backgroundColor: '#95afe5',                                                                                                                                                                        
    height: 50,                                                                                                                                                                                        
    width: 100,                                                                                                                                                                                        
    marginBottom: 5,                                                                                                                                                                                   
    borderRadius: 5,                                                                                                                                                                                   
  },                                                                                                                                                                                                   
});
Run Code Online (Sandbox Code Playgroud)

当您按或删除时,代码会在屏幕上添加和删除一些视图.预计按Add三次然后Remove三次一次将以相同的内存使用量结束.真正发生的是,某些内存未发布,如图所示:

在此输入图像描述

有趣的是,再次添加三次并删除三次内存消耗的峰值低于第一轮并且没有泄漏,但是如果我们改为添加/删除五次则会有额外的伪泄漏.

在此输入图像描述

我称之为伪泄漏,因为有时可以理解为什么,这个保留的内存的很大一部分被释放,但它永远不会回到原始基线.这让我相信这种效果可能不是实际的泄漏,而是某种缓存.

在我的生产应用程序中,此效果已达到150多MB,导致在具有1GB RAM的设备上发生OOM崩溃.

有没有人知道它是什么,是否有办法避免这种行为?

Sha*_*hah 1

也许您的 onPress 属性隐式返回了不必要的数据。如果将 {} 放在箭头后面以防止返回,会发生什么情况。有什么区别吗?

\n

您也许也可以为您的 setState 做一些事情。考虑尝试: setState(() => {\xe2\x80\xa6code})

\n

这也可能有帮助:\n何时使用 React setState 回调

\n