原文链接:https://blog.csdn.net/D_azzle/article/details/83410141

截至到目前为止,本人接触单片机也有将近一年的时间。这一年以来也接触过了很具代表性的单片机,比如51、HT32、STM32等等。但是呢对于单片机的内存一直不了解,一直到现在,在一次单片机编程时我用到了malloc函数为指针分配内存空间。不知道为什么内存一直分配不成功。

所以这才去了解单片机的内存。下图是KELI编译成功后的输出信息。

在这里,我们先只关心Program Size这一行:

Code:代码指令占用的空间;

RO-data:Read Only Data的缩写。它的意义是只读常量占用的空间,比如const型常量、字符串常量等等;

RW-data:Read Write Data的缩写。它的意义是可读可写并且已初始化了的遍历所占用的空间,比如全局变量,静 态变量等等;

ZI-data:Zero Initialize Data的缩写。它的意义是以0初始化的变量,比如未初始化赋值的全局变量、静态变量等等;

而对单片机烧写程序时,FLASH被占用的空间大小为:Code + RO Data + RW Data,但是程序运行时使用到的RAM空间大小为:RW Data + ZI Data。

Why?

FALSH中被占用的空间 == 代码指令  + 只读数据值 + 已初始化变量的值。那么为什么程序运行时占用RAM空间大小 == RW Data + ZI Data呢?

我们都知道,在代码运行机制上单片机不同于PC,单片机的程序通常是在FALSH中直接取指执行,而PC是先把程序拷贝到RAM中再取指执行。因此单片机的RAM中不会存在Code拷贝(除非使用特殊方法强行使程序拷贝到了RAM中执行)。另外单片机RAM中也不会存在RO-data拷贝,因为RO-data是只读数据,为了节省RAM空间,这种数据在执行时直接从FLASH中取出使用,无需再复制到RAM。又由于RW Data和ZI Data是可读可写数据,为了供程序运行时正常读写,于是就会被放在单片机的RAM中(单片机的FLASH区不能被程序改写)

那么对于局部变量来说(RW Data和ZI data都是指的是全局变量或者静态变量),在C语言中全局变量和静态变量在RAM中都有一个特定的地址(存于静态区),而局部变量没有特定的地址。因此局部变量会被存放于堆栈中,当函数入栈时系统就会在栈顶开辟一段内存供局部变量使用,函数出栈时该内存就会被释放掉(静态局部变量除外)。

那么单片机程序在运行时RAM的使用量就等于RW Data + ZI Data了吗?还有没有其他因素会导致RAM占用变化?

玩过PC的都知道,一个程序在运行时它在内存中的占用情况是会随时改变的,这其中可能有压栈入栈和堆块的申请与释放等事件发生,那么在单片机里难道就没有这样的过程了吗?

其实单片机的RAM中也有堆栈区,因此程序运行时RAM的使用量就不会再等于RW Data + ZI Data了。(STM32的堆栈是存放于SRAM中的)而是等于 RW Data + ZI Data + Stack_Size + Heap_Size;

另外编译器并不会给变量一个内存,而是在内存中为变量指定一个地址,然后让其他变量不会重复指向该地址。在编译时编译器会把变量名用地址替换掉,这样也就达到了“编译器给变量分配了内存”的效果。那么,因为编译器为每个变量分配地址且不会让该地址被占用,由此可知RW Data 和 ZI Data这两块数据在被分配好内存之后一直会处于无法被回收的状态。因此如果没有新的程序烧录至单片机,RW Data + ZI Data区占用的空间是不会变的。

而对于堆栈区,堆栈区的大小是由启动文件确定的。函数入栈、出栈的过程变化的只是区内的数据而不是堆栈区的大小(入栈数量超过了栈区的大小限制则为爆栈)。因此没有新的程序烧录至单片机,堆栈区的大小也不会改变。

结论:ARM单片机中的FLASH占有量 == Code + RO Data + RW Data,程序运行时RAM的占有量 == RW Data + ZI Data + Stack_Size + Heap_Size

在KEIL下查看单片机编程内存使用情况的更多相关文章

  1. 操作系统复习——如何查看一个进程的详细信息,如何追踪一个进程的执行过程 ,如何在 Linux 系统下查看 CPU、内存、磁盘、IO、网卡情况?epoll和select区别?

    1. 如何查看一个进程的详细信息,如何追踪一个进程的执行过程 通过pstree命令(根据pid)进行查询进程内部当前运行了多少线程:# pstree -p 19135(进程号) 使用top命令查看(可 ...

  2. Linux查看CPU和内存使用情况 【转】

    Linux查看CPU和内存使用情况 在系统维护的过程中,随时可能有需要查看 CPU 使用率,并根据相应信息分析系统状况的需要.在 CentOS 中,可以通过 top 命令来查看 CPU 使用状况.运行 ...

  3. 测试页面,页面里边一次加载50张不同的图片,每张5M以上,查看浏览器的内存使用情况

    测试页面 1.需要你写个测试页面,页面里边一次加载50张不同的图片,每张5M,查看浏览器的内存使用情况 2.可以10张 递增的方式测试 3.图片需要缩放,比如所有图片缩放成600*800的比例 目的 ...

  4. Linux查看CPU和内存使用情况总结

    Linux查看CPU和内存使用情况:http://www.cnblogs.com/xd502djj/archive/2011/03/01/1968041.html 在做Linux系统优化的时候,物理内 ...

  5. 如何正确查看Linux机器内存使用情况

    如何正确查看Linux机器内存使用情况 背景 只要工作上涉及到Linux机器,基本上都会有这样一个需求,查看内存使用情况,但是怎么看才正确呢?之前使用的是top命令,一直存在一个误区. 为什么top命 ...

  6. 如何使用Linux命令行查看Linux服务器内存使用情况?

    一个服务器,最重要的资源之一就是内存,内存够不够用,是直接关系到系统性能的关键所在. 本文介绍如何查看Linux服务器内存使用情况, 1.free命令 free -m [root@localhost ...

  7. linux下对进程按照内存使用情况进行排序

    linux下对进程按照内存使用情况进行排序的命令为:ps aux --sort -rss 详细解说参见 http://alvinalexander.com/linux/unix-linux-proce ...

  8. 查看Linux服务器内存使用情况

    一个服务器,最重要的资源之一就是内存,内存够不够用,是直接关系到系统性能的关键所在. 本文介绍如何查看Linux服务器内存使用情况, 1.free命令 free -m [root@localhost ...

  9. ubuntu下查看服务器的CPU详细情况

    https://www.cnblogs.com/liuq/p/5623565.html 全面了解 Linux 服务器 - 1. 查看 Linux 服务器的 CPU 详细情况 ubuntu下查看服务器的 ...

随机推荐

  1. .Net 单元测试框架xUnit使用

    使用前需要导入下面的NuGet包:(不然可能会导致测试代码无法运行) .net版本 .net core3.1 Moq这个包只有需要Mock的时候才需要导入(不清楚Mock的话可以留言或自行百度) 开始 ...

  2. MySQL锁这块石头似乎没有我想的那么重

    前言 前言为本人写这篇文章的牢骚,建议跳过不看.   之前好几次都想好好的学习MySQL中的锁,但是找了几篇文章,看了一些锁的类型有那么多种,一时间也没看懂是什么意思,于是跟自己说先放松下自己,便从书 ...

  3. Python开发的入门教程(九)-列表生成式

    介绍 本文主要介绍Python中列表生成式的基本知识和使用 生成列表 要生成list [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],我们可以用range(1, 11): >&g ...

  4. Apache Pulsar 社区周报:08-08 ~ 08-14

    关于 Apache Pulsar Apache Pulsar 是 Apache 软件基金会顶级项目,是下一代云原生分布式消息流平台,集消息.存储.轻量化函数式计算为一体,采用计算与存储分离架构设计,支 ...

  5. 深入了解Kafka【一】概述与基础架构

    1.概述 Kafka是一个分布式的.基于发布订阅的消息系统,主要解决应用解耦.异步消息.流量削峰等问题. 2.发布订阅模型 消息生产者将消息发布到Topic中,同时有多个消息消费者订阅该消息,消费者消 ...

  6. Mybatis参数传递及返回类型

    mybatis参数传递: 单个参数:不做特殊处理        #{参数名}:取出参数值    多个参数:做特殊处理        多个参数会被封装成一个map            key:para ...

  7. python爬取拉勾网职位信息-python相关职位

    import requestsimport mathimport pandas as pdimport timefrom lxml import etree url = 'https://www.la ...

  8. 将大量数据批量插入Oracle表的类,支持停止续传

    之前用create table select * from XXTable无疑是创建庞大表的最快方案之一,但是数据重复率是个问题,且数据难以操控. 于是我在之前批量插数据的基础上更新了一个类,让它具有 ...

  9. Oracle SQL Developer中查看解释计划Explain Plan的两种方法

    方法一: 比如要查看解释计划的SQL是:select * from hy_emp 那么在输入窗口输入: EXPLAIN PLAN FOR select * from hy_emp 之后执行,输出窗口会 ...

  10. mysql InnoDB引擎是否支持hash索引

    看一下mysql官方文档:https://dev.mysql.com/doc/refman/5.7/en/create-index.html , 从上面的图中可以得知,mysql 是支持hash索引的 ...