• 优化内存_内存泄漏——C


    内存泄漏:  动态申请内存,没有正常释放,后续又申请内存,也没释放内存,导致内存池被全部被占用,最终再申请内存的时候失败;严格点则每次申请内存的时候判断申请到的指针是否为空,若为空NULL则表示申请失败。程序正常运行的时候,隔断时间查看内存使用率,如果在没有任何操作的情况下内存使用率在不停增加,则很可能就是动态申请的内存没有释放。
     

    内存分配未成功,却使用了它。

      编程新手常犯这种错误,因为他们没有意识到内存分配会不成功。常用解决办法是,在使用内存之前检查指针是否为NULL。如果指针p是函数的参数,那么在函数的入口处用assert(p!=NULL)进行

      检查。如果是用malloc或new来申请内存,应该用if(p==NULL) 或if(p!=NULL)进行防错处理。

    C内存管理(详细): 
    http://blog.csdn.net/maybe3is3u5/article/details/52067150
     
    http://espressif.com/zh-hans/support/explore/faq?keys=
    如何优化 ESP8266 应用的内存使用?

    通过以下四种方法可以优化 ESP8266 应用的内存使用,减少应用的内存占用空间。

       

    1. 将字符串放到 Flash 中:

    (1) 有些字符串可以放在 Flash 中,特别是长字符串,例如 HTML 请求和响应模板。

    比如,一个字符串原来是用 define 定义的:

    #define test_string    "hello world”

    现在可以定义成如下:

    static const char test_string[] ICACHE_RODATA_ATTR = "hello world";

        

    (2) 当用 ICACHE_RODATA_ATTR 定义字符串常量时,需要对数据内容进行四字节对齐读取。由于 Flash 中的数据需要四字节对其读取,所以定义一个宏获取对齐后的字符串长度:

    #define GET_ALIGN_STRING_LEN(str)    ((strlen(str) + 3) & ~3)

    使用字符串时,动态分配一个新的数组对象,读写 Flash 中的数据。然后用 os_memcpy API 来复制数据内容:

    unsigned int str_len = GET_ALIGN_STRING_LEN(test_string);

    char *tmp_string = (char *)os_malloc(str_len);

    os_memcpy(tmp_string, test_string, str_len);

        

    (3) 在用户的应用代码里使用 tmp_string 进行操作,而不使用 test_string。此方法除了减少应用的 RAM 占用空间,也能解决由于对 Flash 中的数据进行非对齐读取时,在应用中引起的 exception。

    …….

       

    (4) 当用户代码中,无需再使用通过以上方法读取的数据,需要释放之前分配的内存空间

    os_free(tmp_string);

    注意:如果不释放之前分配的内存空间,重复分配内存将会减少核心功能所需的内存,导致 API 出现功能异常或失败。

       

    2. 把 const 数据放到 Flash:

    (1) uint32 类型的数组可以直接放到 Flash,比如:

    const uint32 array[4] ICACHE_RODATA_ATTR = {0x11111111, 0x22222222, 0x33333333, 0x44444444};

    可以直接使用 array[0]。

        

    (2) 对于 uint8 和 uint16 类型的数组,要注意读取数据的时候要四字节对齐,

    比如:

    const uint8 array[7] ICACHE_RODATA_ATTR = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};

       

    (3) 如果需要按字节读取 char 数组当中的元素,可从软件上进行处理,先按四字节读取,然后再按偏移取当中的一个字节。如果直接读取 array[0],会导致 crash。

       

    (4) 对于数据结构,通常做法是分配比用户需要读取的结构更大的内存,从 Flash 四字节读取数据到内存。如同方法 1,在代码中依然使用对象指针。修改代码操作内存中的数据结构,而不是读取数组。

        

    3. 将调试字符串放到 Flash 中:

    现在默认的 printf 打印的字符串都还是放在 RAM 区,占用部分内存。如果用户无需频繁打印日志文件,或者调试字符串太长,可以使用优化的 os_printf 把打印的字符串放到 Flash 而不是 RAM 中。

       

    4. 避免使用全局数组变量:

    全局数组变量会在应用的整个生存期中占用不必要的内存。为减少全局数组变量的使用,乐鑫提供了动态内存分配 API。在基于事件的编程中,请使用 os_malloc 和 os_free 来动态分配所需的内存空间。但注意,我们不建议过于频繁地分配和释放大小不等的内存空间。

  • 相关阅读:
    Linux系统中压缩与解压缩
    Linux系统中的信息查找命令
    Paraview处理fluent计算结果
    insert_stream 中的 insert_every报错
    LIGGGHTS出现错误提示ERROR: Volume expectancy too small
    影响CFD计算量的因素分析及在OpenFOAM中的参数调整
    常见物理量的单位在OpenFOAM中的形式
    LIGGGHTS运行命令
    汇编系列10-内存
    汇编系列9-通用寄存器
  • 原文地址:https://www.cnblogs.com/fyp7077/p/7890443.html
Copyright © 2020-2023  润新知