[英]Is calloc exactly the same as malloc + memset?
在Linux中,calloc是否與malloc + memset完全相同,還是取決於確切的linux / kernel版本?
我對是否可以撥出比物理上更多的RAM的問題特別感興趣(因為您肯定可以分配比物理上更多的RAM,因此無法寫入)。 換句話說,calloc是否總是按照規范建議實際寫入已分配的內存。
當然,這取決於實現,但是在現代Linux上,您可能可以。 最簡單的方法是嘗試它,但是我是根據以下邏輯說這一點。
你可以malloc
比你有(物理+虛擬)內存更多的是因為你的內存的內核延遲分配,直到你真正使用它。 我相信這是為了增加程序由於內存限制而不會失敗的機會,但這不是問題。
calloc
與malloc
相同,但零初始化內存。 當您要求Linux提供一頁內存時,Linux已經對其進行了零初始化。 因此,如果calloc
可以告知所請求的內存只是從內核請求的,則實際上不必將其初始化為零! 由於沒有,因此無法訪問該內存,因此它應該能夠請求比實際更多的內存。
如評論中所述, 此答案提供了很好的解釋。
calloc
是否需要寫入內存取決於它是從已經分配給該進程的堆頁面中獲取分配,還是必須請求內核將更多內存分配給該進程(使用諸如sbrk()
或mmap()
)。 當內核為進程分配新內存時,它總是首先將其清零(通常使用VM優化,因此實際上不必寫入頁面)。 但是,如果要重用先前分配的內存,則必須使用memset()
將其歸零。
在引用的副本中或此處未提及。 Linux使用虛擬內存,並且可以分配系統中物理可用的更多內存。 單純地在用戶空間中執行malloc()
和memset()
的calloc()
簡單實現將觸及每個頁面。
由於Linux通常以4k塊進行分配,因此所有calloc()
塊都是相同的,最初讀取為零。 那就是相同的4k內存塊可以被映射為只讀 ,而整個calloc()
空間僅占用大約size/4k * pointer_size + 4k
。 當程序寫入calloc()
空間時,發生頁面錯誤,Linux將分配一個新頁面(4k)並繼續執行該程序。
簡稱寫時復制或COW 。 malloc()
行為通常相同。 對於小尺寸文件, “ C”庫將使用合並並與其他小尺寸分配共享4k頁。
因此,通常涉及兩層。
如果請求的內存大小很大,並且需要為進程分配新的內存,則上述大多數情況都適用(通過Linux的進程內存管理)。 但是,如果請求的內存很小,則它將類似於malloc()
加memset()
。 在較大的分配大小中, memset()
會因為接觸內存而損壞,內核認為它需要新的頁面來分配。
您不能將malloc(3)
內存增加到內核執行malloc(3)
-ing所提供的進程的數量。 如果您無法分配要分配的內存量,則malloc(3)
返回NULL。 另外, malloc(3)
和memset(3)
是由您的c庫( libc.so
)而不是您的內核定義的。 Linux內核定義了mmap(2)
和其他低級內存分配函數,而不是*alloc(3)
系列(不包括kalloc()
)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.