打印

转 静态分配和动态分配内存的区别

[复制链接]
581|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
爱笑的panhutu|  楼主 | 2017-3-29 16:45 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
说白了,内存的静态分配和动态分配的区别主要是两个:
  一是时间不同。静态分配发生在程序编译和连接的时候。动态分配则发生在程序调入和执行的时候。
  二是空间不同。堆都是动态分配的,没有静态分配的堆。栈有2种分配方式:静态分配和动态分配。静态分配是编译器完成的,比如局部变量的分配。动态分配由函数malloc进行分配。不过栈的动态分配和堆不同,他的动态分配是由编译器进行释放,无需我们手工实现。

对于一个进程的内存空间而言,可以在逻辑上分成3个部份:代码区,静态数据区和动态数据区。动态数据区一般就是“堆栈”。“栈(stack)”和“堆(heap)”是两种不同的动态数据区,栈是一种线性结构,堆是一种链式结构。进程的每个线程都有私有的“栈”,所以每个线程虽然代码一样,但本地变量的数据都是互不干扰。一个堆栈可以通过“基地址”和“栈顶”地址来描述。全局变量和静态变量分配在静态数据区,本地变量分配在动态数据区,即堆栈中。程序通过堆栈的基地址和偏移量来访问本地变量。
        
一般,用static修饰的变量,全局变量位于静态数据区。函数调用过程中的参数,返回地址,EBP和局部变量都采用栈的方式存放。


首先,在使用动态分配内存技术前,必须明白自己在做什么,这样做与其它的方法有什么不同,特别是会产生哪些负面影响,天下没有免费的午餐。动态分配内存与静态分配内存的区别:

1) 静态内存分配是在编译时完成的,不需要占用CPU资源;动态分配内存是在运行时完成的,动态内存的分配与释放需要占用CPU资源; 
2) 静态内存分配是在栈上分配的,动态内存是堆上分配的; 
3) 动态内存分配需要指针或引用数据类型的支持,而静态内存分配不需要; 
4) 静态分配内存需要在编译前确定内存块的大小,而动态分配内存不需要编译前确定内存大小,根据运行时环境确定需要的内存块大小,按照需要分配内存即可。可以这么说,静态内存分配是按计划分配,而动态内存分配是按需分配。 
5) 静态分配内存是把内存的控制权交给了编译器,而动态内存是把内存的控制权交给了程序员;

综上所述,静态分配内存适合于编译时就已经可以确定需要占用内存多少的情况,而在编译时不能确定内存需求量时可使用动态分配内存;但静态分配内存的运行效率要比动态分配内存的效率要高,因为动态内存分配与释放需要额外的开销;动态内存管理水平严重依赖于程序员的水平,如果处理不当容易造成内存泄漏。那么再具体些,如何选择内存分配方式,如果动态分配内存需要注意哪些问题呢?

需要强调的是,由于动态分配内存把内存的控制权交给了程序员,程序员有义务写代码确认内存分配成功能,如果分配失败要做适当处理,否则将给你的程序进而下一个定时炸*,随时有可能因为动态内存分配失败而导致程序崩溃。

1. 全局变量尽可能不要动态分配内存。

  既然将变量定义为全局变量,就为了其可见范围比较宽,因为可能这些变量在整个程序的运行期都是可见的,可能根本就没有机会释放全局变量所占用的内存,所以使用动态分配内存是意义不大的,只能给程序带来额外的运行负担。 
  但对于全局变量内存大小不能确定的情况,可能会有例外。比如要处理一批数据,数据的大小可能由用户通过控制台参数形式告诉程序,这种情况可以动态按需分配内存,合理使用内存。 
  而对于编译时能够确定内存使用量的全局变量,而且变量工作期(暂且这么叫吧,就是该变量还可能会被用到的这段时期)又与程序的运行期相同的情况根本没有必要动态分配内存。这种情况很有意思,就是使用动态分配内存,但可以不考虑释放这块内存,因为可以释放内存的时候该程序也要退出了,程序一结束,进程也就结束了,整个程序所在的虚拟空间已经被全部释放,也就没必要去添加释放内存的代码了。(但我确定见到过这样的代码)

2. 动态分配内存时,分配与释放的代码要对称。

  这里说的分配与释放的代码对称指,分配内存的代码要与释放内存的代码在同一个范围的代码域中,例如在一个函数的开头申请内存,就应该在这个函数的结尾释放内存,否则,如果在一个函数内部分配内存,在函数外释放内存,就有可能因程序员的疏忽造成内存泄漏;如果内存分配在某个类的构造函数中,那么就应该在析构函数中释放内存,千不要在另外一个函数中释放,而等着客户代码去掉用那个函数去手动释放内存,如果那样的话就相当于埋了一个定时炸*,随时可能因为一时的疏忽而造成内存泄漏。

3. 对动态创建的对象或分配的内存块一定要检查期有效性。

  由于操作系统的并发性和复杂性,任何一次动态内存的分配操作都有可能失败,特别是申请一次较大块内存时。所以一定要检查动态创建的对象或申请的堆内存是否成功,否则可能因为错误的指针或空指针造成程序异常,如果异常没有得到适当处理的话,可能使整个程序意外终止,造成损失。

4. 尽可能少次数地使用动态内存分配。

  动态分配是在运行时由操作系统完成的,所以是要消耗CPU资源的,在进行动态内存分配时尽可能便利已经分配的资源。如果上次申请的资源够用就不要重新申请资源,不够用时才释放旧资源,申请新资源。

5. 在保证资源利用率的前提下,能用静态内存分配不用动态分配,特别是局部临时对象。

  例如,对于局部对象,使用静态分配的内存,可以由编译器编译时分配,超出作用域自动内存,不仅减小了程序代码,减少了错误产生的概率,减轻了程序员的负担,而且提高的程序的执行效率,何乐而不为呢?


转载于江苏三艾网络

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

50

主题

53

帖子

1

粉丝