日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

glibc(ptmalloc)内存暴增问题解决

發布時間:2025/7/25 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 glibc(ptmalloc)内存暴增问题解决 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

from:http://blog.chinaunix.net/uid-18770639-id-3385860.html


點擊(此處)折疊或打開

  • #include <stdio.h>
  • #include <stdlib.h>
  • #include <string.h>

  • int main()
  • {
  • ????int alloc_time = 4000;
  • ????char *a[alloc_time];
  • ????char *b[alloc_time];

  • ????int i, j;
  • ????for(i=0; i<alloc_time; i++)
  • ????{
  • ????????a[i] = (char *)malloc(52722);
  • ????????memset(a[i], 1, 52722);
  • ????????b[i] = (char *)malloc(1);
  • ????????memset(b[i], 1, 1);
  • ????}
  • ????printf("malloc finished\n");
  • ????for(i=alloc_time-1; i>=0; i--)
  • ????{
  • ????????free(a[i]);
  • ????????free(b[i]);
  • ????}
  • ????printf("free finished\n");
  • ????//char *p = (char *)malloc(2000);
  • ????//free(p);

  • ????while(1){
  • ????????sleep(3);
  • ????}
  • }

  • 運行這個測試程序,發現Glibc內存暴增,程序已經把內存返回給了Glibc庫,但Glibc庫卻沒有把內存歸還給操作系統。

    分析:

    ptmalloc使用chunk結構來實現內存管理。用戶free掉的內存并不是都會馬上歸還給系統,ptmalloc會統一管理heap和mmap映射區域中的空閑chunk。當用戶進行下一次分配請求時,ptmalloc會首先試圖在空閑的chunk中挑選一塊給用戶,這樣就避免了頻繁的系統調用,降低了內存分配的開銷。對于空閑的chunk,ptmalloc采用分箱式內存管理方式,根據空閑chunk的大小和處于的狀態將其放在三個不同的容器中。

    bins:ptmalloc將相似大小的chunk用雙向鏈表鏈接起來,這樣的一個鏈表被稱為一個bin。bins有128個隊列,前64個隊列是定長的(small bins),每隔8個字節大小的塊分配在一個隊列,后面的64個隊列是不定長的(largebins),就是在一個范圍長度的都分配在一個隊列中。所有長度小于512字節的都分配在定長的隊列中,后面的64個隊列是變長的隊列,每個隊列中的chunk都是從大到小排列的。

    ?unsort隊列(只有一個隊列),它是一個cache,所有free下來的如果要進入bins隊列中都要經過unsort隊列,分配內存時會查看unsorted bin中是否有合適的chunk,如果找到滿足條件的chunk,則直接返回給用戶,否則將unsorted bin中所有chunk放入bins中。

    fastbins,大約有10個定長隊列,它是一個高速緩沖,所有free下來的并且長度是小于max_fast(默認80B)的chunk就會進入這種隊列中。進入此隊列的chunk在free的時候并不修改使用位,目的是為了避免被相鄰的塊合并掉。

    如果內存塊是空閑的,它會掛在其中的一個隊列中,它是通過復用的方式,使用空閑chunk的第3個字和第4個字當作它的前鏈和后鏈(變長塊是第5個字和第6個字)。

    ?

    malloc的步驟:

    1.????????先在fastbins中找,如果能找到,從隊列中取下后(不需要再置使用位為1)立刻返回;

    2.????????判斷需求的塊是否在small bins(bins的前64個bin)范圍,如果在小箱子范圍,并且剛好有滿足需求的塊,則直接返回內存地址;

    3.????????到了這一步,說明需要分配的是一塊大內存,或者小箱子里找不到合適的chunk;這個時候,會觸發consolidate,ptmalloc首先會遍歷fastbins中的chunk,將相鄰的chunk合并,并鏈接到unsorted bin中(因為在大箱子找一般都要切割,所以要優先合并,避免過多碎片);

    4.????????在unsort bin中取出一個chunk,如果能找到剛好和想要的chunk相同大小的chunk,立刻返回,如果不是想要的chunk大小的chunk,就把它插入到bins對應的隊列中去,轉到2。

    5.????????到了這一步,說明需要分配的是一塊大的內存,或者small bins和unsorted bin中都找不到合適的chunk,并且fastbins和unsorted bin中所有的chunk都清楚干凈了。在large bins中找,找到一個最小的能符合需求的chunk從隊列中取下,如果剩下的大小還能建一個chunk,就把chunk分成兩個部分,把剩下的chunk插入到unsort隊列中取,把chunk的內存地址返回;

    6.????????如果搜索fastbins和bins都沒有找到合適的chunk,那么就需要操作topchunk(是堆頂的一個chunk,不會放在任何一個隊列里)來進行分配了。在topchunk找,如果能切出符合要求的,把剩下的一部分當作topchunk,然后返回內存地址;

    7.????????到了這一步說明topchunk也不能滿足分配要求,就只能調用sysalloc,其實就是增長堆了,然后返回內存地址。


    free的步驟:

    1.????????判斷所需釋放的chunk是否為mmapedchunk,如果是,則調用munmap釋放mmaped chunk,解除內存空間映射,該空間不再有效,然后立刻返回;

    2.????????如果和topchunk相鄰,直接和topchunk合并,不會放到其他的空閑隊列中取,然后立刻返回;

    3.????????如果釋放的大小小于max_fast(80字節),就把它掛到fastbins中去返回,使用位仍然為1,當然更不會去合并相鄰塊,然后立刻返回;

    4.????????如果釋放塊得大小介于80—128K,把chunk的使用位置為0,判斷前一個chunk是否處于使用中,如果前一塊也是空閑塊,則合并,并轉入下一步;

    5.????????判斷當前釋放chunk的下一個塊是否為topchunk,如果是,則轉到第7步,否則轉下一步;

    6.????????判斷下一個chunk是否處在使用中,如果也是空閑的,則合并,并將合并后的chunk掛到unsort隊列中去;

    7.????????如果執行到了這一步,說明釋放了一個與top chunk相鄰的chunk;則無論它有多大,都將它與topchunk合并,并更新topchunk的大小等信息,轉下一步;

    8.????????如果合并后的大小大于FASTBIN_CONSOLIDATION_THRESHOLD(64K),也會觸發consolidate,即fastbins的合并操作,合并后的chunk會被放到unsortedbin中,fastbins將變為空,操作完成之后轉下一步;

    9.????????試圖收縮堆。(判斷topchunk的大小是否大于mmap的收縮閾值,默認為128KB)。

    ?

    ptmalloc對于大于128K的塊通過mmap方式來分配,小于128K(mmap分配閾值)的塊在heap中分配。堆是通過brk的方式來增加或壓縮的,如果在現有的堆中不能找到合適的chunk,會通過增長堆的方式來滿足分配,如果堆頂的空閑塊超過一定的閾值會收縮堆,所以只要堆頂的空間沒釋放,堆是一直不會收縮的。因為ptmalloc的內存收縮是從top chunk開始,如果與top chunk(堆頂的一個chunk)相鄰的那個chunk在內存池中沒有釋放,top chunk以下的空閑內存都無法返回給系統,即使這些空閑內存有幾十個G也不行。

    按照這個測試程序分配后,內存變成由小塊和大塊交替出現,釋放小塊的時候,直接把小塊放在fastbins中取,而且他的使用位還是1,釋放大塊的時候,它試圖合并相鄰的塊,但是和它相鄰的塊的使用位還是1,所以它不能把相鄰的塊合并起來,而且釋放的塊的大小小于64K,也不會觸發consolidate,即不會把fastbins清空,所以當所有的塊都被釋放完后,所有的小塊都在fastbins里面,使用位都還是1,大塊都掛在unsort隊列里面。全部都無法合并。所以使用的堆更加無法壓縮。如果在循環后面再分配2000字節然后釋放的話,所有內存將全部被清空,這是因為再申請2000字節的時候,由malloc的第二步,程序會先調用consolidate,即把所有的fastbins清空,同時把相鄰的塊合并起來,等到所有的fastbins清空的時候,所有的塊也被合并起來了,然后調用free(2000)的時候,這塊將被合并起來,成為topchunk,并且大小遠小于64K,所有堆將會壓縮,內存歸還給系統。

    ?

    解決方法:

    減小mmap分配閾值,對于大內存塊分配盡量采用mamp系統調用直接向操作系統分配,回收時用munmap返回給操作系統。但是這種做法會降低ptmalloc的分配釋放效率,因為系統調用mamp是串行的,操作系統需要對mmap分配內存加鎖,而且操作系統對mmap的物理頁強制清0很慢。
    這個可以通過修改 MALLOC_MMAP_THRESHOLD_環境變量或者調用mallopt()接口來實現。

    總結

    以上是生活随笔為你收集整理的glibc(ptmalloc)内存暴增问题解决的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: a色视频| 亚洲天堂网站 | 激情文学亚洲 | 91精品91久久久中77777老牛 | 国产一级伦理片 | 91国内精品久久久 | 国内少妇毛片视频 | 天天5g天天爽免费观看 | 高跟鞋和丝袜猛烈xxxxxx | 在线免费看av的网站 | yy4138理论片动漫理论片 | 日韩在线网址 | 日本黄色录相 | 国产情侣一区二区三区 | 免费毛片大全 | 久久大 | 爱爱网站免费 | 特黄一区二区 | 成人国产片 | 最新中文字幕在线观看 | 噼里啪啦免费看 | 欧美日韩成人一区二区在线观看 | 无码人妻aⅴ一区二区三区有奶水 | 日本91网站 | 中文字幕一二三四 | 久久刺激| 未满十八18禁止免费无码网站 | 一级全黄裸体免费观看视频 | 狠狠艹狠狠干 | 中文字幕黄色片 | 日韩精品在线一区二区三区 | 粉嫩小箩莉奶水四溅在线观看 | 五月天亚洲综合 | 日日夜夜爱 | 天天插美女 | 人人妻人人爽人人澡人人精品 | 在线观看网址你懂的 | 国产福利影院 | 激情综合一区二区三区 | 欧美性吧 | 国产91热爆ts人妖系列 | av视屏| 亚洲色图美腿丝袜 | 麻豆国产精品视频 | 久久精品国产精品亚洲毛片 | 超碰国产91 | 一级片视频免费看 | 99人妻碰碰碰久久久久禁片 | 欧美性爱视频久久 | 亚洲中文字幕在线观看 | 亚洲第一视频 | 精品午夜一区二区三区在线观看 | 亚州av在线播放 | 亚洲一片 | 黄色一级大片在线观看 | 欧美一级艳片视频免费观看 | 337p粉嫩大胆色噜噜狠狠图片 | 久久av免费观看 | 色午夜视频 | 91亚洲专区 | 永久免费精品视频 | 91日本在线| 日本人的性生活视频 | 国产做爰xxxⅹ性视频国 | 亚洲好看站 | 男人影院在线观看 | www.久久av.com| 久久精品国产清自在天天线 | 国产一区二区三区91 | 欧美极品视频在线观看 | 在线看国产视频 | 特级a级片 | 成人午夜免费网站 | 91在线无精精品白丝 | 2017狠狠干 | 91在线亚洲 | 国产福利在线导航 | 在线免费观看av不卡 | 韩国国产在线 | 好吊一区| 免费又黄又爽又色的视频 | 日本无遮羞调教打屁股网站 | 操你啦在线视频 | 国产欧美日韩 | 国产一区二区三区精品愉拍 | 懂色av成人一区二区三区 | 日韩在线三级 | 69久久久久久 | 青春草在线视频观看 | 亚洲人精品| 鲁鲁狠狠狠7777一区二区 | 欧美性猛交xxx乱大交3蜜桃 | 超碰成人97 | 成人免费视频网站在线观看 | 亚洲影院中文字幕 | 欧美午夜精品一区二区三区 | 一级片www | 朝桐光在线视频 | 午夜精品福利视频 |