C++编程实践——资源耗尽和栈溢出

一、内存问题

在前面的文章中反复分析过内存的相关异常,也提到过资源耗尽(Exhaustion)和栈溢出(Overflow)。不管是前者还是后者,遇到这种情况,对于C++程序来说,基本就只有Crash的结果了。针对这两种情况,本文将对二者进行对比分析。

二、栈溢出

顺道提一嘴,一般来说,堆是堆,栈是栈,但如果直接提“堆栈”,习惯是指栈,但还是要根据上下文进行具体分析。栈溢出,通常是指栈的空间不足,即地方不够大了。栈是由系统来控制管理的,栈的大小都是有限制的。这种限制,在大小上来讲,是非常严格的。正常情况下,都会限制在M级。相对于现在的内存大小,这已经是很小的了。所以,这种小内存在应用中就会非常容易陷入空间不足的境界。常见的导致栈溢出的原因有:

  1. 无控制的过深的递归
  2. 较大的局部变量如数组或对象等
  3. 函数调用堆栈过深(这个和递归调用类似)

常见的栈溢出的实际场景,多见于线程内的递归调用和较大的局部数组。直接的函数调用过深,这种还是比较少见的。

三、资源耗尽

而资源耗尽就是一个更为常见的现象,特别是其中的内存耗尽。如果大家有早期的UI开发的经验,特别是MFC之类的开发经验,早期会常见一些资源耗尽导致的程序问题,比如画笔、HDC等等。其实不光界面会有这种情况,诸如文件句柄、锁、IO等等。
导致资源耗尽的的原因主要有:

  1. 超限制的分配,如不受控的循环、递归等导致的资源分配耗尽
  2. 资源泄露,特别是在长时间运行的程序中,不断的释放但未回收,极易导致资源耗尽
  3. 资源的不匹配,比如内存碎片过多,虽然有内存,但无法分配大于碎片大小的内存

四、应对的方法

对于上述问题的应对之法,其实在C++中还是有相对成熟的方法,
对栈溢出常用的方法有:

  1. 严格限定递归或循环的终止条件
  2. 严格控制栈上变量分配的大小
  3. 严格进行代码走查并借用相关工具进行分析
    对资源耗尽常用的方法有:
  4. 使用智能指针来处理大多数的内存泄露的问题,当然也要防备其中的一些特殊情况,如循环引用的问题
  5. 使用RAII,自动处理资源的控制
  6. 使用资源池,并设置限定阀值,防止出现意外情况,如内存池、线程池等
  7. 在编码级别进行代码走查并借助相关工具进行分析,如内存常见的cppcheck等

五、总结

基础的问题是一种沉默的问题,它可能不会怎么影响大多数的代码开发,但真到了见直章时,关键的细节把控往往是解决问题的“封喉”一剑。所以,对技术的学习和提高需要开发者把基础打牢,特别是大梁一定要坚固无比。这才是可以构建更高楼层的方法。

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值