随笔 - 733  文章 - 2  评论 - 12  阅读 - 92万

堆内存 栈内存 虚拟内存 动态内存管理

从编译器角度来看内存分三种情况:

1 系统初始化时都已经确定好、不会再变动的内存区域,一般指的是全局变量、静态变量数组等。

2 栈上内存:一般指的是函数内部的局部变量等,函数调用时分配内存,调用结束后系统自动释放不用自己考虑回收,效率高。有时候栈需要自己设定,设定不当可造成栈溢出。

3 堆上内存:即用动态分配函数分配的内存属于堆上内存,适合那些有MMU(内存管理)、开始不确定需要申请多大内存的场合。注意:利用动态分配内存函数,使用完毕要及时释放内存和将指针清0,否则容易产生野指针和内存泄露。因为系统不负责释放。同时频繁调用还容易造成内存随便,需要涉及内存碎片整理和回收算法。

虚拟内存和直接操作内存:

嵌入式系统一般资源有限,通常开发者直接对内存分区,对内存操作需要开发者对内存的整体使用情况有了解。ucos在系统初始化时先将内存分为几个固定大小的缓冲池,任务申请内存从某个缓冲池中申请内存,用完后释放回内存池。

PC机一般资源丰富,上层应用程序开发者通过虚拟内存来操作,屏蔽底层的实际物理内存地址。

指针 数组和栈:

指针是语言工具,动态分配函数都通过指针来操作。

数组和栈都属于数据结构。对于数据量小且固定的可以使用静态存储结构的数组;函数调用一般是栈的操作,注意堆栈的设置要合理。避免堆栈深度不足,造成调用时参数丢失;堆栈深度过深,效率变低。

堆栈及生长方向

  堆栈本质上是先进后出的结构,压栈栈顶上移动,出栈栈顶下移。堆栈是由内存分配的,嵌入式系统的每个独立任务都需要有自己的独立栈空间,但为其分配时我们就要知道堆栈相对内存的增长方向:假如栈顶增长是从内存的低地址到高地址即“水往高处流”则栈是向上增长的,否则是向下增长的。

  如果用C语言判断栈的增长方向需要注意这和编译器是怎么处理的也是相关的,所以仅通过2个局部变量来判断是不妥的。我们知道栈主要用在函数的入参,举报变量和返回值,所以可以通过参数和举报变量的地址来判断:参数地址比局部变量地址值大则是向下的,否则是向上的。

posted on   杰瑞鼠  阅读(1033)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示