连续的存储空间分配(2.2.2)

看了一点算法章节的,感觉看得非常辛苦。想跳去数据结构章节看看怎么样,结果对于我来说依然是晦涩难懂。数据结构第二节讲的是线性结构,第一小节简单地介绍了一下常用的线性结构,有堆栈、队列和双端队列。然后开始讲存储空间分配的方法,第二小节讲连续存储空间的分配,第三小节讲链表形式的分配。

感觉上课学的数据结构真的是弱爆了,对于连续存储空间分配我的反应只有数组,各种添加和删除操作。但是书里分析的却是这样一种情况,有n个堆栈(每一个都需要连续存储空间)以及一大段连续的存储空间,怎样才能合理分配,并且内存溢出时怎样处理。注意为了更高效的利用内存空间,堆栈的大小是可变的,就像一个可以动态改变大小的数组一样。

有一个比较简单的方法,当某一个堆栈溢出的时候,分别向前和向后找,看是否有其他堆栈有多余的空间,找到以后通过整体向前或向后平移数据从而腾出一个空间给溢出的堆栈。但这种方法仅仅是处理了堆栈溢出的情况并不能减少堆栈溢出的发生次数,我们可以通过合理地初始化各个堆栈的大小来减少堆栈溢出次数。比如说,若每一个堆栈预计的大小都相同,则我们可以将它们平均分配到整段内存中。可是无论做出怎样合理的初始化,都仅仅可以减少有限次数的堆栈溢出,而且一般情况下只是在程序运行的早期阶段比较有效。

基于这种情况,书中又提出了一种更好的方法,在堆栈溢出后不仅仅给溢出的堆栈分配多一个元素空间,而是根据所有堆栈的增长速度重新给它们分配内存空间,以预留更多的空间给增长速度快的堆栈。现在假设共有n个堆栈,堆栈i溢出,处理过程是这样的:

G1.算出现在所有的剩余空间大小SUM,算出上一次空间分配到现在各个堆栈所增加的元素数量之和INC

G2.若SUM小于0,内存就满了。否则在这里设置两个神奇的参数,α=0.1*SUM/n,β=0.9*SUM/INC。意思大概是α代表在10%的剩余空间平均分配给每一个堆栈,β代表剩下的90%按全部堆栈从上一次空间分配到现在增长的总数量成比例地分成若干小份,这里的α与β是小数。

G3.重新计算各个堆栈的基地址(空间的重新分配实质上就是基地址的重新分配),神奇的设置公式如下:NEWBASE[1]=BASE[1],也就是说第一个堆栈的起始位置是固定不变的,而对于其他堆栈j=2,3,……,n,x=y+α+D[j-1]*β,其中D[k]是栈k的增长数量,y的初始值为0,NEWBASE[j]=NEWBASE[j-1]+TOP[j-1]-BASE[j-1]+x(向下取整)-y(向下取整),y=x。可以看出堆栈之间一般来说都会有剩余空间,因为存在10%的平均分配,而当堆栈的增长数量较大时,就会按比例从90%中分配更多空间给它,感觉这实际上是一种趋势的分析,有迅速增长的趋势,那就预留更多的空间。

G4.重新装入各个元素。这里的方法也有点小神奇。问题在于如何避免在元素平移的过程中不覆盖掉有效的数据,可能出现覆盖数据的情况有两种,一是在元素向下平移时覆盖掉后一个堆栈的数据,二是元素向上平移时覆盖掉前一个堆栈的数据。对于向上平移的情况,假设要平移堆栈i,存在两种可能,BASE[i-1]…NEWBASE[i-1]…NEWBASE[i]…BASE[i]…和NEWBASE[i-1]…BASE[i-1]…NEWBASE[i]…BASE[i]…,前一种情况,明显NEWBASE[i-1]…NEWBASE[i]间的长度比BASE[i-1]…NEWBASE[i]的还要短,因此堆栈i-1里面的元素肯定不会在NEWBASE[i]的后面,因此不会覆盖;后一种情况,若堆栈i-1的元素足够多的话,就有可能位于NEWBASE[i]的后面了,所以这里用一种方法,从前面的堆栈开始进行向上平移,即先对堆栈i-1进行向上平移再对堆栈i进行平移。对于向下平移的情况有,BASE[i]…NEWBASE[i]…NEWBASE[i+1]…BASE[i+1]…和BASE[i]…NEWBASE[i]…BASE[i+1]…NEWBASE[i+1]…,分析是一样的,可能出现覆盖的就后一种情况,这时从后面的堆栈开始进行向下平移就可以了,就是说先对堆栈i+1向下平移再平移堆栈i。

上述方法的性能很难用准确的数学方法去描述,大概的规律是若总内存还有一半剩余的时候性能是比较好的,需要重新分配空间的次数很少,当剩余空间越来越少时性能会逐渐变坏。若内存已经所剩无几了,堆栈溢出的情况会变得非常多,而且重新装入元素花费的时间会变得很长,而实际上很多程序如果快要把内存用光了,那它一般很快就会真正地用光内存,这时候依然是出问题。这种情况下在程序快用光内存时对空间的重分配的消耗就是浪费的,因为最终还是会出问题。因此可以设置一个阈值,当剩余空间低于这个阈值的时候就报错,不再执行空间的重分配。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值