2010-05-06 21 views
27

Windows具有VirtualAlloc,它允許您保留一個連續的地址空間區域,但實際上不使用任何物理內存。稍後當你想使用它(或其中的一部分)時,你再次調用VirtualAlloc來提交以前保留頁面的區域。任何方式來保留但不提交在Linux內存?

這實際上是非常有用的,但我想最終將我的應用程序移植到Linux上 - 所以如果稍後無法移植它,我不想使用它。 Linux有辦法做到這一點?

編輯 - 使用案例

我想分配4 GB的或一些這樣的虛擬地址空間,但只承諾其64K一次。這將給我一個零拷貝的方式來增長一個高達4 GB的數組。這很重要,因爲典型的陣列大小和副本的兩倍會爲非常大的陣列帶來看似隨機的不可接受的延遲。

+0

什麼樣的用例可以滿足您的需求?爲什麼分開詢問您是否可以分配空間(保留它)和實際使用內存空間? – dlamotte 2010-05-06 16:18:12

+0

它看起來像定期撥款應該工作正常。如果不使用內存,它將被換出,並且,當你開始使用它時,它將被帶回到mmeory – Drakosha 2010-05-06 16:29:37

+1

@xyld:一個從虛擬地址空間中扣除塊,另一個從虛擬內存中扣除它(頁面文件)。 – 2010-05-06 17:02:45

回答

25

mmap一個特殊的文件,像/dev/zero(或使用MAP_ANONYMOUS)作爲PROT_NONE,以後使用mprotect提交。

+0

是的。無論如何,當您正常分配任意大小的內存塊時,C庫/內核就會隱式地執行此操作。頁面被保留,但在你觸摸它們之前並沒有實際映射。映射/ dev/zero(使用MAP_PRIVATE)只是一種特殊的malloc。 – MarkR 2010-05-06 20:48:37

+1

@MarkR:對於linux來說,vm overcommit sysctl的某些設置是正確的。 '/ dev/zero'方法的mmap應該可以在任何POSIX操作系統上運行,包括禁用了vm overcommit的linux。讀取vm overcommit文檔時,'/ dev/zero'和無寫訪問的組合是導致該塊不計入提交限制的原因。 – 2010-05-06 23:07:58

5

您可以通過使用內核過度使用來在系統範圍內啓用此功能。這通常是許多發行版的默認設置。

這裏是解釋http://www.mjmwired.net/kernel/Documentation/vm/overcommit-accounting

+0

哦,那很酷......雖然只有一個過程無法打開它,但是呢? – dlamotte 2010-05-06 16:59:57

+0

@dlamotte:它通常在桌面系統上默認啓用。實時系統會對這種行爲(以及一般的需求 - 分頁)感到沮喪,但這對桌面系統是有利的,而且我還沒有遇到過那種尚未開啓的系統。只要你不寫入你分配的內存(通過幾乎任何方式)內核只會保留它。 – 2015-09-20 11:33:15

4

與Linux相當的VirtualAlloc()mmap(),它提供了相同的行爲。然而正如一位評論者指出的那樣,只要內存沒有被初始化(例如calloc()或用戶代碼),連續內存的保留就是對malloc()調用的行爲。

+0

你說得對,我驚訝地發現它是在你鏈接的malloc文檔中指定的。 – Eloff 2010-05-06 17:45:09

+2

順便說一句,只有malloc,我能夠在linux x64機器上分配虛擬地址空間的128TB,大小爲4GB(2^15-3左右),開銷約500MB(實際上太低那麼每個4kb頁面都有一個頁表條目,但是對於每個2MB頁面的8個字節條目(內核中支持透明的巨大頁面)恰到好處? – Eloff 2013-05-14 12:07:24

1

「看似隨意的不可接受的延遲 對於非常大的陣列

您還可以考慮m鎖()或mmap()的+ MAP_LOCKED,以減輕傳呼的影響。許多CPU支持巨大(又名大)頁面,大於4kb的頁面,這些較大的頁面可以減輕TLB對流式讀/寫的影響

+1

問題仍然是複製,即使沒有分頁它也太慢要複製一個2GB的數組來創建一個4GB的數組,如果你可以避免移動內存,那麼添加第20億和1個元素就不會有這種延遲。 – Eloff 2013-05-14 12:11:28

相關問題