2011-07-30 39 views
15

我正在編寫一個算法來執行一些外部內存計算,即輸入數據不適合主內存的地方,您必須考慮I/O的複雜性。每個進程的物理內存限制

既然我的測試中,我並不總是想用真正投入我想的可用內存量限制到我的過程。我所發現的是,我可以設置mem內核參數,以限制所有進程的實際使用的內存(是正確的嗎?)

有沒有辦法做同樣的,但有一個每個進程限制 。我看過ulimit,但它僅限制每個進程的虛擬內存。任何想法(也許我甚至可以在我的C++代碼中以編程方式設置它)?

+0

你依靠虛擬內存以及Linux對相關數據加載到內存分頁,或你打算將數據手動加載到緩衝區中嗎? –

+0

我使用虛擬內存+ LINUX的分頁(加上一個名爲stxxl一些外部存儲器中的數據結構庫,但我已經可以控制這些的內存使用情況) – dcn

+1

增加Linux內核的標籤,因爲你可能需要直接與內核談這個,並且內核人員最可能知道它。 –

回答

11

您可以嘗試'cgroups'。 要使用它們,以root身份鍵入以下命令。

# mkdir /dev/cgroups 
# mount -t cgroup -omemory memory /dev/cgroups 
# mkdir /dev/cgroups/test 
# echo 10000000 > /dev/cgroups/test/memory.limit_in_bytes 
# echo 12000000 > /dev/cgroups/test/memory.memsw.limit_in_bytes 
# echo <PID> > /dev/cgroups/test/tasks 

其中是您要添加到cgroup的進程的PID。請注意,該限制適用於分配給此cgroup的所有進程的總和。

從這一刻開始,這些過程被限制到物理存儲器和身體屬性+交換的12MB 10MB。

有在該目錄中的其他可調參數,但具體名單將取決於你所使用的內核版本。

您甚至可以創建限制的層次結構,只需創建子目錄即可。

該cgroup是繼承的,當你叉/ EXEC,因此,如果您添加從你的程序的推出,它會自動分配一個cgroup中的殼。

請注意,您可以將cgroups安裝在任何您想要的目錄中,而不僅僅是/ dev/cgroups。

+0

我應該能夠驗證使用'/ proc//status'和'VmHWM'條目來滿足限制,對吧? – dcn

+0

我不確定這是如此簡單。比較/ proc//status與cgroups/*/memory.usage_in_bytes,它們有些不同。可能與共享內存或虛擬內存有關......我認爲cgroups只限制進程請求的新內存,但是在進程添加到cgroup之前存在的共享內存不計算在內。查看文檔[here](http://www.kernel.org/doc/Documentation/cgroups/memory.txt)。 – rodrigo

+0

接受這個答案:cgroups爲我工作。 '-omemory'是否是拼寫錯誤(沒有空格)?無論如何,我發現它更舒適,相應地設置cgconfig並直接在cgroup(cgexec)中啓動我的過程,例如http://jlebar.com/2011/6/15/Limiting_the_amount_of_RAM_a_program_can_use.html – dcn

5

我不能提供一個直接的答案,但關於做這樣的東西,我通常寫我自己的內存管理系統,這樣我可以有存儲區域的完全控制權,有多少我分配。當你編寫微控制器時,這通常也是適用的。希望能幫助到你。

+1

+1只是跟蹤自己的內存使用情況的簡單方法。 –

5

我會使用帶有RLIMIT_AS參數的setrlimti來設置虛擬內存的限制(這是ulimit的作用),然後讓進程使用mlockall(MCL_CURRENT | MCL_FUTURE)來強制內核故障並鎖定爲物理內存RAM所有的程序頁面,所以這個過程

+0

'mlockall'確實存在問題。除了一個事實,即在某些情況下,你真的想限制的物理內存,並享受交換(例如,桌面應用程序),一些編程語言(例如,golang或Java)分配一個巨大的使用mmap + PROTO_ANON虛擬空間量,所以你不能使用它們。即使你使用C++,你也不能使用asan之類的東西。 –

+0

(剛剛通知我其實知道是誰給了答案,小世界的傢伙...) –

1

內核mem=啓動參數限制如何在總操作系統的內存將使用量的虛擬==物理內存量。

這幾乎從不是用戶想要的。

對於物理內存,還有RSS RLIMIT又名RLIMIT_AS

+0

你的意思是RLIMIT_RSS? – dcn

+1

的醫生說大約RLIMIT_RSS「這種限制僅在由於Linux 2.4.X,X <30效應」 ...... – dcn

+1

哎,每次物理內存被稱爲「記憶的cgroup」的過程實際上RLIMIT,否則更多或更少的任何保證。 http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=blob;f=Documentation/cgroups/memory.txt;h=6f3c598971fc3ef05d2ebfb0e6e8879b3047d839;hb=HEAD – adobriyan

2

你有沒有考慮在某種虛擬環境中試用你的代碼?虛擬機可能對您的需求太多,但像User-Mode Linux可能是一個很好的選擇。這將在您的常規操作系統內運行一個Linux內核作爲一個單獨的進程。然後你可以提供一個單獨的mem=內核設置,以及一個單獨的交換空間來進行受控實驗。

1

正如其他海報已經指出,了setrlimit是最有可能的解決方案,它控制的過程環境的所有配置方面的限制。使用此命令來查看您的shell過程中,這些單獨的設置:

ulimit -a 

是最相關的輸出結果中您的方案的人如下:

data seg size   (kbytes, -d) unlimited 
max locked memory  (kbytes, -l) 64 
max memory size   (kbytes, -m) unlimited 
virtual memory   (kbytes, -v) unlimited 

結帳的手冊頁了setrlimit(」 man setrlimit「),它可以從您的C/C++代碼以編程方式調用。過去,我曾用它來控制堆棧大小的限制。 (順便說一句,對於的ulimit沒有專門的手冊頁,它實際上是一個嵌入式bash命令,因此它在bash的手冊頁。)