网站收录提交工具,灰色行业怎么推广引流,阿里云服务器怎么使用,外贸管理网站模板/*如果你使用linux, douglea malloc已经默认作为glibc的malloc,新的版本可能用的是ptmalloc(dlmalloc的多线程版本)如果你用的bsd4.2及以前系统libc用的kingsley的malloc;BSD(包括freebsd,netbsd,openbsd)4.2以后版本libc用的是PHKmalloc;如果你用的windows系统用的是microsoft…/*如果你使用linux, douglea malloc已经默认作为glibc的malloc,新的版本可能用的是ptmalloc(dlmalloc的多线程版本)如果你用的bsd4.2及以前系统libc用的kingsley的malloc;BSD(包括freebsd,netbsd,openbsd)4.2以后版本libc用的是PHKmalloc;如果你用的windows系统用的是microsoft的分配器算法;不过其他各个系统很容易使用doug lea malloc替换现有的malloc*///c语言标准库提供的malloc函数请注意malloc的几个return出口;void* mALLOc(size_t bytes){//0~4bytes-nb16;4bytes-nbbytes2个4字节头然后对其到8byteschecked_request2size(bytes, nb);//如果在fastbin中有可用的块直接从fastbin中分配if ((unsigned long)(nb) (unsigned long)(av-max_fast)) {fb (av-fastbins[(fastbin_index(nb))]);if ( (victim *fb) ! 0) { //静态变量成员fastbin初始化为0*fb victim-fd;check_remalloced_chunk(victim, nb);return chunk2mem(victim);}}//如果是512bytes的小块请求,从smallbin中取一块if (in_smallbin_range(nb)){//根据nb大小定位到smallbinidx smallbin_index(nb);bin bin_at(av,idx);//如果该大小的bin列表不为空if ( (victim last(bin)) ! bin){if (victim 0) //静态变量成员smallbin初始化是0malloc_consolidate(av);//第一次进来这里调用init_state函数进行初始化else {//有空闲块/* victim|\/bin-first_chunk-chunk-chunk-...-last_chunk| /\---------------------------------|*///按上图将victim从链表中删除,设置victim的下一块的pbitinuse//将victim块返回给应用return chunk2mem(victim);}}}else {//512bytes,先释放fastbin中的块idx largebin_index(nb);if (have_fastchunks(av)) //初始化的时候静态变量0这个条件成立malloc_consolidate(av); //合并fastbin中的chunk,放入unsorted_bin}//这里是唯一将chunks放入bin的地方//处理最近被释放或剩余的chunks如果上次小请求没有完全匹配//分割出小chunk就会发生//最外面的for(;;)需要因为我们无法知道在malloc结束前有合并操作//因此需要多尝试一次最多多循环一次for(;;){/*unsorted chunks所有的从一个chunk中分割出来的剩余chunk首先放到unsorted chunks链表中下次malloc调用中有一次被再次使用的机会。作为一个队列维护。当free或malloc_consolidate函数中 将剩余chunk放入unsorted chunks链表而在malloc函数中被分配或放入其他 正常bin中。*///循环unsorted中每一块与插入顺序相反从后面开始匹配查找while ( (victim unsorted_chunks(av)-bk) ! unsorted_chunks(av)) {bck victim-bk;//victim:unsorteds last chunk;bck:unsorteds last-two chunksize chunksize(victim);if (in_smallbin_range(nb) //512bytes bck unsorted_chunks(av) //unsorted队列中只有一块 victim av-last_remainder //并且这一块是上一次分割剩下的 (unsigned long)(size) (unsigned long)(nb MINSIZE)) //剩余的chunk必须大于MINSIZE{//分割nb出去剩余的继续放在reminder和unsorted中return chunk2mem(victim);}//unsorted_bin中多于一块chunk,或者剩余一块但不是上一次分割剩余的//或者剩余的一块大小太小继续向下//把最后一块从unsorted freelist中删除unsorted_chunks(av)-bk bck;bck-fd unsorted_chunks(av);//如果正好完全匹配则returnif (size nb) {set_inuse_bit_at_offset(victim, size);check_malloced_chunk(victim, nb);return chunk2mem(victim);}//不是完全匹配就从unsorted_bin移到normal_bin中if(in_smallbin_range(size)){}else//注意large-bin中的内存块是有序的,FIFO{}}//end while//对于512bytes的请求,使用best-fit策略查找当前bin//注意当前bin是根据应用请求的size直接index定位到的binif (!in_smallbin_range(nb)) {//best-fitif ((victim last(bin)) ! bin //empty or //first最大但也不能满足请求(unsigned long)(first(bin)-size) (unsigned long)(nb)) {//从后往前找找到第一个满足请求的while (((unsigned long)(size chunksize(victim)) (unsigned long)(nb)))victim victim-bk;//如果剩余的大小if (remainder_size MINSIZE) {return chunk2mem(victim);}else{//分割该块,返回给应用,剩余的块 放入unsorted-binreturn chunk2mem(victim);}}}//如果unsorted-bin,当前bin都没有满足的,依次查找下一个更大的bin直到找到一个满足的为止for (;;) {//这里使用了bitmap技巧快速查找到匹配的large-bin,具体信息可以参考其他文章//bit map说明这个32位中bit后面的bin都是空/*bit0??啥意思,index%320index-bit32 -1 2^01 -2 2^12 -4 2^2...31 - 2^31*/if (bit map || bit 0) {//bit怎么会是0??? //从下一个32开始do {if (block BINMAPSIZE) /* out of bins */goto use_top; //所有bin都找完了还没找到,跳到下面use_top} while ( (map av-binmap[block]) 0);bin bin_at(av, (block BINMAPSHIFT));bit 1;//从第一位开始}//......//如果找到一块满足的将该块进行分割//如果剩余的大小if (remainder_size MINSIZE) {return chunk2mem(victim);}else{//分割该块,返回给应用,剩余的块 放入unsorted-binreturn chunk2mem(victim);}}//end for(;;),遍历normal-bin//如果所有bin都没有可用的块use_top://如果top足够大,从top取一块return给用户修改top指针if ((unsigned long)(size) (unsigned long)(nb MINSIZE)) {return chunk2mem(victim);}//上面入口处如果请求512bytes会触发合并fastbin//在这里:如果fastbins无法满足,smallbins也无法满足,//而后合并fastbins放入unsorted_bins,//对于大块再到unsorted_bins找,如果没有精确匹配放入normal_bin//然后再到normal_bins找best-fit//如果还没找到扩展top//由此可知如果请求smallsize则不会触发上述合并fastbins//然后会触发到unsorted_bins查找只有一块上次剩余的小块才会//被分配或者精确匹配否则放入normal_bins//然后不管larger或small都到normal_bins中查找//所以在这里对fastbins合并再尝试一次else if (have_fastchunks(av)) {assert(in_smallbin_range(nb));malloc_consolidate(av);idx smallbin_index(nb); /* restore original bin index */}else //top也没法满足向OS扩展内存return sYSMALLOc(nb, av);}}//最外层的for(;;)//end}