文章首发于浩瀚先森博客

堆栈的概念在脑海里已经存在有一段时间了,今天就测试来整理下Heap堆。栈以后再说。

堆区不像全局变量和局部变量总是有指定的内存大小,它是为了在程序运行时动态分配内存而设定的一块区域。

在程序运行时需要一块特定大小的内存空间来使用的时候,那么可以先声明空间大小值,然后在程序运行时会在某个区域里划分指定大小的内存空间出来,这里所说的某个区域就是堆区。

堆内存通常用类似malloc,free的函数来分配内存大小和释放内存。

Malloc函数用来动态分配堆内存空间。成功分配空间后返回分配的内存地址指针。如果申请分配的空间大小大于堆的大小就返回NULL。

Free函数用来释放先前分配的空间(创建堆空间后一定要记得释放)。

动态分配内存的时候由于存在内存指针和内存大小的关系,可能会导致overhead,反复分配和注销空间的话也会发生fragment问题.

实现动态分配内存的方法有很多种,在IAR Compiler里使用最多的是dlmalloc方法。

想要了解更多关于动态分配内存的可以点这里C dynamic memory allocation

看下面的例子

我们设定Heap的大小为512Byte,然后申请分配461byte空间。结果我们可以看到因为无法分配461Byte的空间导致返回NULL.

因为overhead导致最大只能使用460byte空间。

另外,由于overhead的原因,与一次性分配大空间内存相比,分多次来分配小一点内存空间,反而使我们能够使用的总内存空间更少。

下面的例子是每次分配10byte,结果第30次的时候就无法再分配内存了。计算一下总共也只分配了290byte。

而在第一个例子里一次性分配大内存空间的时候最多反而可以分配460byte。

综上所说与多次分配小内存相比,一次性分配大内存方式使得能使用的最大heap空间更多。

在写嵌入式程序的时候,不像PC上内存资源丰富,嵌入式板子内存资源有限,必须准确的分配好heap堆的空间大小。然后预测一个程序要使用多少的heap空间,需要分配多大的heap并不是一件容易的事。

IAR EWARM提供能够查询堆使用量的函数。利用提供的函数我们就可以预测程序大概需要多大的heap空间。

下面介绍部分动态分配内存相关的库函数

在使用IAR提供的库函数之前需要进行下面的操作

在项目中添加IAR EWARM安装目录下的​arm\src\lib\dlmalloc.c文件

NO_MALLINFO 设置为 0

NO_MALLOC_STATS设置为0

1. __iar_dlmalloc_stats

标准输出(stdout)heap空间总大小以及heap使用量。

2. __iar_dlmallinfo

返回包含heap大小以及使用情况的结构体。

    Mallinfo结构体信息参照下面内容。

#if !NO_MALLINFO
/*
mallinfo()
Returns (by copy) a struct containing various summary statistics: arena: current total non-mmapped bytes allocated from system
ordblks: the number of free chunks
smblks: always zero.
hblks: current number of mmapped regions
hblkhd: total bytes held in mmapped regions
usmblks: the maximum total allocated space. This will be greater
than current total if trimming has occurred.
fsmblks: always zero
uordblks: current total allocated space (normal or mmapped)
fordblks: total free space
keepcost: the maximum number of bytes that could ideally be released
back to system via malloc_trim. ("ideally" means that
it ignores page restrictions etc.) Because these fields are ints, but internal bookkeeping may
be kept as longs, the reported values may wrap around zero and
thus be inaccurate.
*/
struct mallinfo dlmallinfo(void);
#endif /* NO_MALLINFO */

更改heap堆大小

依照下面的方式可以设置使用heap堆的大小。

Heap堆大小在项目option的Linker选项里设置。

在Linker的Config里 点击Edit来变更Linker的设置。

在Stack/Heap Sizes选项卡里变更heap堆大小。

分配的heap堆大小可以再map文件里查看确认。

Heap堆的理解以及在IAR中如何设置堆的大小的更多相关文章

  1. Android代码中动态设置图片的大小(自动缩放),位置

    项目中需要用到在代码中动态调整图片的位置和设置图片大小,能自动缩放图片,用ImageView控件,具体做法如下: 1.布局文件 <RelativeLayout xmlns:android=&qu ...

  2. vue中动态设置echarts画布大小

    document.getElementById('news-shopPagechart').style.height = this.heightpx2+'px'; //heightpx2定义在data ...

  3. Java堆的理解

    堆的核心概述 所有的对象实例以及数组都应当在运行时分配在堆上 从实际实用角度看 --"几乎所有的对象实例都在堆中分配内存" 数组和对象可能永远不会存储在栈上,因为栈帧中保存引用,这 ...

  4. c#中栈和堆的理解

    之前对栈(stack)和堆(heap)的认识很模糊,今天看了一篇关于堆栈的文章<译文---C#堆VS栈>后,仿佛有种拨开云雾见青天的感觉,当然只是一些浅显的理论的认识,这里做一些简单的记录 ...

  5. 栈 堆 stack heap 堆内存 栈内存 内存分配中的堆和栈 掌握堆内存的权柄就是返回的指针 栈是面向线程的而堆是面向进程的。 new/delete and malloc/ free 指针与内存模型

    小结: 1.栈内存 为什么快? Due to this nature, the process of storing and retrieving data from the stack is ver ...

  6. .NET中栈和堆的比较 #1

    原文出处:http://www.c-sharpcorner.com/UploadFile/rmcochran/csharp_memory01122006130034PM/csharp_memory.a ...

  7. 关于c语言中栈和堆释放的问题

    #include<iostream> #include<string> using namespace std; int main() { string st; cin> ...

  8. 《深入理解Java虚拟机》(六)堆内存使用分析,垃圾收集器 GC 日志解读

    堆内存使用分析,GC 日志解读 重要的东东 在Java中,对象实例都是在堆上创建.一些类信息,常量,静态变量等存储在方法区.堆和方法区都是线程共享的. GC机制是由JVM提供,用来清理需要清除的对象, ...

  9. Java中栈和堆讲解

    之前对JVM中堆内存和栈内存都是一直半解,今天有空就好好整理一下,用作学习笔记. 包括Java程序在内,任何程序在运行时都是要开辟内存空间的.JVM运行时在内存中开辟一片内存区域,启动时在自己的内存区 ...

随机推荐

  1. 【转】Xcode进阶快捷键

    Xcode 快捷键和手势不仅节省了宝贵的工作时间,而且能让你在工作过程中感到更自信.能力变得更强,这样的工作方式也更合理.学习下列技巧你将成为 Xcode 资深用户. 此处提供一些通用的按键符以供参考 ...

  2. ListView实现点击事件以及总结

    差点吓死我了,好不容易写的博客没有了,还好有自动保存功能,不然我真的是呜呜... ---恢复内容开始--- 开学一个月了,终于可以看见自己的作品雏形了. 从一个小白到现在半年了,觉得日子过得比较充实, ...

  3. 1、软件工程师要阅读的书籍 - IT软件人员书籍系列文章

    软件工程师要阅读的书籍估计是项目组内最多的.软件工程师处于项目组中最基础的人员储备阶层,与项目的关系最密切.当然,现在是大数据时代,我们无法全部看完所有相关的书籍,只能够先学习工作需要的知识,然后在项 ...

  4. SELECT CAST(GETDATE() AS VARCHAR(10)) 显示不同格式的原因

    开发人员测试时,发现生产服务器与测试服务器执行SELECT CAST(GETDATE() AS VARCHAR(10))语句显示的格式不一样.如下所示 Server A Server B 其实出现这个 ...

  5. CLR via C# 读书笔记---常量、字段、方法和参数

    常量 常量是值从不变化的符号.定义常量符号时,它的值必须能在编译时确定.确定后,编译器将唱两只保存在程序集元数据中.使用const关键字声明常量.由于常量值从不变化,所以常量总是被视为类型定义的一部分 ...

  6. MySQL优化概述

    一. MySQL优化要点 MySQL优化是一门复杂的综合性技术,主要包括: 1 表的设计合理化(符合 3NF,必要时允许数据冗余) 2.1 SQL语句优化(以查询为主) 2.2 适当添加索引(主键索引 ...

  7. 多重共线性的解决方法之——岭回归与LASSO

          多元线性回归模型 的最小二乘估计结果为 如果存在较强的共线性,即 中各列向量之间存在较强的相关性,会导致的从而引起对角线上的 值很大 并且不一样的样本也会导致参数估计值变化非常大.即参数估 ...

  8. 把Tomcat注册为windows服务

    配置环境变量 JAVA_HOME=D:\java CLASSPATH=.;%JAVA_HOME%\lib; PATH=%JAVA_HOME%\bin; 提示:一般jre默认在jdk目录下%JAVA_H ...

  9. day1 基础总结

    学习博客地址: http://www.cnblogs.com/alex3714/articles/5465198.html 低级语言:接近硬件底层 高级语言:接近用户思维 编程语言: 1. 编译型:c ...

  10. [已解决]Teamviewer VPN 连接上,但无法ping

    用Teamveiwer 可以进行远程控制连接.用了VPN功能后,起先也正常.可以PING和其他网络操作. 后来忽然始终VPN连接上后,无法PING和做其他的网络操作了. 检查缘由是对方TeamView ...