You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ESP32升级MicroPython 1.22.2后urequests.post报内存错误16求助

问题分析与解决方案

问题概述

基于MicroPython 1.18开发的ESP32定位项目,升级到1.22.2版本后,执行urequests.post请求HTTPS地址时触发内存错误16(ENOMEM);改用HTTP请求后程序不再崩溃,但服务器返回仅支持HTTPS的错误,精简程序也无法解决问题。

核心原因

MicroPython 1.22.2的SSL/TLS栈实现相比1.18版本有更新,对内存的占用更高。ESP32的可用RAM有限(尤其是GENERIC固件默认配置下),HTTPS请求需要完成SSL握手、加密解密等操作,这些流程会占用大量内存,当剩余RAM不足以支撑这些操作时,就会触发内存不足错误。

可行解决方案

  • 手动触发垃圾回收:在发起请求前调用gc.collect()释放闲置内存,减少内存碎片:

    import gc
    def getLocation():
        global lng,lat,acu,udf
        gc.collect()  # 请求前回收内存
        headers = {"Content-Type": "application/json"}
        locationStr = "https://www.googleapis.com/geolocation/v1/geolocate?key=" + APIKey
        try:
            response = urequests.post(locationStr, headers=headers, data=ujson.dumps(data))
            location = ujson.loads(response.content)
            lng = location["location"]["lng"]
            lat = location["location"]["lat"]
            acu = location["accuracy"]
            print ("the current Location is lat %s, Log %s with accuracy %s" % (lat,lng,acu))
            response.close()
        except:
            print("unable to read the current location %s" %OSError)
    
  • 分块读取响应内容:避免一次性加载整个响应到内存,改用分块读取解析,降低内存峰值:

    # 替换原有的location = ujson.loads(response.content)
    response_data = b""
    while chunk := response.read(64):  # 每次读取64字节
        response_data += chunk
    location = ujson.loads(response_data)
    
  • 使用精简版ESP32固件:选择MicroPython提供的ESP32_GENERIC_SMALL固件,该固件禁用了部分非必要功能,能为用户程序预留更多RAM。

  • 优化SSL配置:指定TLS版本为TLS 1.2(Google API支持该版本),同时关闭非必要的hostname验证,减少SSL栈的内存开销:

    import ssl
    def getLocation():
        global lng,lat,acu,udf
        gc.collect()
        headers = {"Content-Type": "application/json"}
        locationStr = "https://www.googleapis.com/geolocation/v1/geolocate?key=" + APIKey
        # 配置精简SSL上下文
        ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
        ctx.check_hostname = False
        try:
            response = urequests.post(locationStr, headers=headers, data=ujson.dumps(data), ssl=ctx)
            # 后续解析代码...
    
  • 精简请求数据:检查data变量的内容,去除不必要的字段,最小化发送的JSON数据大小,减少内存占用。

内容的提问来源于stack exchange,提问作者Ahmed Ali

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 06:44:59