百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

单片机上运行Python——MicroPython(二)

bigegpt 2024-09-05 12:13 4 浏览

在前一篇文章中,已经介绍了单片机上进行Python编程的一些注意点,详见:单片机上运行Python——MicroPython(一)。本篇就接着介绍后续内容,想要获取更多内容可以关注我哦。

堆空间

当运行中的程序实例化对象时,所需的RAM资源会从一个固定大小的内存池中被申请和分配,该内存池即为堆空间。当对象超过作用域后(或者说其不再可用时),该对象即被称作"垃圾"资源。此时,一个单独的进程,被称作"垃圾回收器",会收回其所占内存并将其内存返回到可用的堆空间中。该进程会在后台自动运行,你也可以直接显式地使用gc.collect()对该过程进行调用。

如果感觉上述论述稍微有一点点复杂,只需要记住:周期性地进行如下调用即可。

gc.collect()
gc.threshold(gc.mem_free() // 4 + gc.mem_alloc())

内存碎片

比如说一个程序,创建了对象foo后又创建了对象bar。接着,foo超出了作用域但bar仍有效。foo所使用的RAM资源将会被垃圾回收器收回。然而,如果bar分配在高地址空间,仅当新对象空间不大于foo当初所申请的内存大小时,其所收回的空间才可被再次使用。在一个复杂且长期运行的程序中,堆栈因此会变得碎片化:尽管仍然有大量RAM空间可用,但没有充足的连续的空间可用于新对象实例化使用。此时程序便会陷入到内存错误之中。

上面章节所述的编程技巧均旨在减少内存碎片的产生。如果需要使用大的永久性缓冲或其它类型对象,最好在程序运行的早期就进行实例化,以避免内存碎片的影响。若要更进一步改善这种情况,可以监视堆栈的状态并手动控制垃圾回收器的执行。大致方法会在下面章节介绍。

内存状态报告

有许多库函数可用于报告内存的分配情况和控制垃圾回收器的执行。其多存在于gc模块和micropython模块。可将下面的示例代码粘贴到REPL中运行查看效果。(Ctrl+E 进入粘贴模式,然后Ctrl+D运行)

import gc
import micropython
gc.collect()
micropython.mem_info()
print('-----------------------------')
print('Initial free: {} allocated: {}'.format(gc.mem_free(), gc.mem_alloc()))
def func():
    a = bytearray(10000)
gc.collect()
print('Func definition: {} allocated: {}'.format(gc.mem_free(), gc.mem_alloc()))
func()
print('Func run free: {} allocated: {}'.format(gc.mem_free(), gc.mem_alloc()))
gc.collect()
print('Garbage collect free: {} allocated: {}'.format(gc.mem_free(), gc.mem_alloc()))
print('-----------------------------')
micropython.mem_info(1)

上面使用的函数如下:

  • gc.collect() 强制垃圾回收
  • micropython.mem_info() 打印RAM使用情况汇总
  • gc.mem_free() 返回堆栈剩余内存空间字节数
  • gc.mem_alloc() 返回当前已分配的内存字节数
  • micropython.mem_info(1) 以表格形式打印出RAM使用情况

运行时具体产生的结果数据和所用平台有关,但应该能够看到,函数的声明使用了一小部分RAM空间,这部分空间由编译器回收所得。函数运行使用了超过10KB的空间,但其返回时a变成了垃圾资源,因为其已经超出了作用域,不能再被引用了。最后的gc.collect()恢复了内存。

micropython.mem_info(1) 最终的输出细节依平台不同而不同,但其中符号可大致按如下解释:

每个字母代表一个单独的内存块,大小为16字节。所以,堆栈打印输出的每一行代表0x400字节或者1KB的RAM空间。

控制垃圾回收器

任何时候都可以通过调用gc.collect()进行垃圾回收。周期性地进行该操作对系统运行十分有利:既可以减少内存碎片又能够提高系统性能。垃圾回收过程会占用毫秒级的时间,当其它工作较少时该过程会更快一点(在Pyboard上大约为1ms)。在程序的特定位置显式调用垃圾回收过程会最小化其时间延迟消耗。

垃圾回收会在下面情况下被自动触发。某次内存分配失败时,垃圾回收过程会自动执行,然后再重试之前内存分配动作,只有再次分配失败时才会抛出异常。如果可用RAM空间减少到一个阈值时,垃圾回收也会被自动触发。该阈值也能够随着程序的执行自动调整。

gc.collect()
gc.threshold(gc.mem_free() // 4 + gc.mem_alloc())

上述代码表示,当前可用堆栈的大于25%的空间被占用时会触发垃圾回收过程。

通常来讲,模块代码应该在运行时再通过构造函数或其它初始化函数实例化数据对象。因为如果在模块被导入时便实例化数据对象,可能会导致编译器内存不足而无法继续导入后续的模块。如果模块确实需要在被导入时便实例化数据,之后随即调用gc.collect()会改善其所带来的问题。

字符串操作

MicroPython会高效地处理字符串,理解这一点有助于设计能够在单片机上良好运行的程序。当模块被编译时,其中多次出现的字符串会仅存储一次,该过程被称作字符串内嵌化。在MicroPython中,内嵌的字符串被称作qstr。通常,被导入的模块实例存储于RAM空间中,但如以上所述,固化为字节码的模块则会存储于Flash上。

字符串比较也比较高效,其内部使用哈希比较而不是字符对字符的方式。使用字符串而不是整数所带来的代价因此会特别小,无论是从性能方面考虑还是从内存占用方面考虑——这也许对于C程序员而讲比较惊讶。

附记

(1) MicroPython传递、返回和复制(默认情况下)对象时均以引用的方式进行。引用变量仅占用单字存储空间,所以该过程在RAM占用和速度方面效率很高。

当要求使用完整的变量时,不能以字节存储空间或字存储空间引用形式使用,MicroPython中有标准的库,有助于高效地存储这些变量并进行相关类型转换。可以查阅array,ustruct和uctypes模块获取详情。

(2) 在Unix和Windows平台上,gc.collect()函数返回一个整数,其表明本次回收的不同的内存区块数(更准确来说,变得可用的内存块的数目)。考虑到效率方面的原因,单片机上运行的MicroPython版本没有返回值。

相关推荐

Linux gron 命令使用详解(linux gminer)

简介gron是一个独特的命令行工具,用于将JSON数据转换为离散的、易于grep处理的赋值语句格式。它的名字来源于"grepableon"或"grepable...

【Linux】——从0到1的学习,让你熟练掌握,带你玩转Linu

学习Linux并掌握Java环境配置及SpringBoot项目部署是一个系统化的过程,以下是从零开始的详细指南,帮助你逐步掌握这些技能。一、Linux基础入门1.安装Linux系统选择发行版:推荐...

Linux常用的shell命令汇总(linux中shell的作用)

本文介绍Linux系统下常用的系统级命令,包括软硬件查看、修改命令,有CPU、内存、硬盘、网络、系统管理等命令。说明命令是在Centos6.464位的虚拟机系统进行测试的。本文介绍的命令都会在此C...

零成本搭建个人加密文件保险柜(适用于 Win11 和 Linux)

不依赖收费软件操作简单,小白也能跟着做支持双系统,跨平台使用实现数据加密、防删除、防泄露内容通俗无技术门槛,秒懂秒用使用工具简介我们将使用两个核心工具:工具名用途系统支持Veracrypt创建加密虚...

如何在 Linux 中使用 Gzip 命令?(linux怎么用gzip命令)

gzip(GNUzip)是Linux系统中一个开源的压缩工具,用于压缩和解压缩文件。它基于DEFLATE算法,广泛应用于文件压缩、备份和数据传输。gzip生成的文件通常带有.gz后缀,压缩效率...

Linux 必备的20个核心知识点(linux内核知识点)

学习和使用Linux所必备的20个核心知识点。这些知识点涵盖了从基础操作到系统管理和网络概念,是构建扎实Linux技能的基础。Linux必备的20个知识点1.Linux文件系统层级标...

谷歌 ChromeOS 已支持 7z、iso、tar 文件格式

IT之家6月21日消息,谷歌ChromeOS在管理文件方面进行了改进,新增了对7z、iso和tar等格式的支持。从5月的ChromeOS101更新开始,ChromeOS...

如何在 Linux 中提取 Tar Bz2 文件?

在深入解压方法之前,我们先来了解.tar.bz2文件的本质。.tar.bz2是一种组合文件格式,包含两个步骤:Tar(TapeArchive):tar是一种归档工具,用于将多个文件或目录打包...

如何在 CentOS 7/8 上安装 Kitematic Docker 管理器

Kitematic是一款流行的Docker图形界面管理平台,适用于Ubuntu、macOS和Windows操作系统。然而,其他发行版(如CentOS、OpenSUSE、Fedora、R...

Nacos3.0重磅来袭!全面拥抱AI,单机及集群模式安装详细教程!

之前和大家分享过JDK17的多版本管理及详细安装过程,然后在项目升级完jdk17后又发现之前的注册和配置中心nacos又用不了,原因是之前的nacos1.3版本的,版本太老了,已经无法适配当前新的JD...

爬虫搞崩网站后,程序员自制“Zip炸弹”反击,6刀服务器成功扛住4.6万请求

在这个爬虫横行的时代,越来越多开发者深受其害:有人怒斥OpenAI的爬虫疯狂“偷”数据,7人团队十年心血的网站一夜崩溃;也有人被爬虫逼到极限,最后只好封掉整个巴西的访问才勉强止血。但本文作者却走...

Ubuntu 操作系统常用命令详解(ubuntu必学的60个命令)

UbuntuLinux是一款流行的开源操作系统,广泛应用于服务器、开发、学习等场景。命令行是Ubuntu的灵魂,也是高效、稳定管理系统的利器。本文按照各大常用领域,详细总结Ubuntu必学...

Linux面板8.0.54 测试版-已上线(linux主机面板)

Linux面板8.0.54测试版【增加】[网站]Java项目新增刷新列表按钮【增加】[网站]PHP项目-Apache-服务新增守护进程功能【增加】[网站]Python项目创建/删除网站时新增同时创建...

开源三剑客——构建私有云世界的基石

公共云原生的浪潮正在席卷这个世界,亚马逊AWS、谷歌GCP和微软的Azure年收入增长超过了30%,越来越多的公司和个人开始将自己的服务部署到云环境中,大型数据中心的规模经济带来了成本的降低,可以在保...

2.2k star,一款业界领先的私有云+在线文档管理系统

简介kodbox可道云(原KodExplorer)是业内领先的企业私有云和在线文档管理系统,为个人网站、企业私有云部署、网络存储、在线文档管理、在线办公等提供安全可控,简便易用、可高度定制的私有云产品...