数据在内存中存储方式

我们都知道,程序执行是需要内存资源的。不同操作系统对内存的使用方式不同,linux系统,程序执行是从硬盘动态加载到内存执行,执行完成后给硬盘保存。
嵌入式vxWorks系统属于静态加载方式,程序直接全部装载在内存去运行,对于这种处理方法,理论上运行速度优势明显,缺点是内存永远不够。

数据存储方式(如下来自网络,写的比较好):

代码段:代码段是用来存放可执行文件的操作指令,也就是说是它是可执行程序在内存中的镜像。代码段需要防止在运行时被非法修改,所以只准许读取操作,而不允许写入(修改)操作――它是不可写的。

数据段数据段用来存放可执行文件中已初始化全局变量,换句话说就是存放程序静态分配[1]的变量和全局变量。

BSS段:BSS段包含了程序中未初始化的全局变量,在内存中 bss段全部置零。

堆(heap):堆是用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。当进程调用malloc等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张);当利用free等函数释放内存时,被释放的内存从堆中被剔除(堆被缩减)

:栈是用户存放程序临时创建的局部变量,也就是说我们函数括弧“{}”中定义的变量(但不包括static声明的变量,static意味着在数据段中存放变量)。除此以外,在函数被调用时,其参数也会被压入发起调用的进程栈中,并且待到调用结束后,函数的返回值也会被存放回栈中。由于栈的先进先出特点,所以栈特别方便用来保存/恢复调用现场。从这个意义上讲,我们可以把堆栈看成一个寄存、交换临时数据的内存区。

内存分布图(图上框大小不代表内存大小,只是分布):


对于以上内容有点经验的兄弟们都很清楚。那我们为什么还是要深入研究它的存储方式呢?我又不去写操作系统。

以前老员工经常跟我说,了解这些后,可以入手优化代码,提高CPU效率、节省内存。如今做个小通信设备CPU都是1G,可支持内存2G了,而且价格不高。

哎,对编码人是好事还是坏事?但一类问题是CPU和内存等硬件无法帮你解决的,那就是你写代码留下的bug,而且还是一个低概率bug。


以个人遇到的实际问题

1:内存泄露;

2:内存重复释放;

3:内存内容被非法制修改引起异常;

4:栈溢出。

.....太多了。每次遇到这种情况,我就想念java等高级语言。


内存泄露我一直认为是个很简单的东西,分配了就要释放,但这个问题却一直被很多人埋坑。

业务逻辑复杂后,不是你不想释放,是你想不到在哪里释放。

泄露的内存就是在堆中,定位问题时就必须去堆分布段中查找内存是哪个任务malloc.

关于堆内存的管理有很多种算法,另开篇幅介绍。


栈的理解比堆更重要,因为栈承载任务运行以及运行过程中的数据管理。

在系统初始化时,系统会给每个任务分配一个独立的栈空间。

程序运行,函数的调用,局部变量定义,函数返回等都是在此任务独立的栈空间内完成。

如果是从事C语言开发,我认为研究函数调用时栈的产生和恢复,并研究透传,绝对是上层的内功心法,并让你有一种豁然开朗的感觉。

猜你喜欢

转载自blog.csdn.net/Calm_027/article/details/68946266