我有一些函數的大列表(高達500 000)。 我的任務是爲每個函數生成一些圖形(可以獨立於其他函數)並將輸出轉儲到文件(可以是多個文件)。 生成圖的過程可能非常耗時。如何防止在運行並行Java進程時消耗物理內存
我也有40個物理內核和128GB內存的服務器。
我試過用java Threads/ExecutorPool來實現並行處理,但似乎並沒有使用處理器的所有資源。 在某些輸入上,該程序需要長達25小時才能運行,而根據htop,只有10-15個核心正在工作。
所以我嘗試的第二件事是創建40個不同的進程(使用Runtime.exec)並將它們分開。 此方法使用處理器所有資源(所有40個核心上的負載均爲100%),並且前一個示例中的性能提升高達5倍(對於我的任務,這隻需要5個小時)。 但是這個方法的問題是,每個java進程都是獨立運行的,並且獨立於別人使用內存。有些情況下,所有128GB的RAM在並行工作5分鐘後纔會消耗。我現在使用的一種解決方案是,如果Runtime.totalMemory> 2GB,則爲每個進程調用System.gc()。這會降低總體性能(先前輸入爲8小時),但會將內存使用量限制在合理範圍內。 但此配置僅適用於我的服務器。如果您在運行40核心和64GB的服務器上運行它,則需要調整Runtime.totalMemory> 2GB條件。
所以問題是避免這種積極的內存消耗的最好方法是什麼?
運行單獨的進程以執行並行作業是否正常嗎?
在Java中有沒有其他的並行方法(可能是fork/join?),它使用100%物理資源的處理器。
多少個線程是在'Executor'? – kgeorgiy
fork/join在內部使用執行程序池。 – kgeorgiy
是否有原因讓Java不能使用所有128GB的RAM?如果沒有其他需要,它會浪費。自己調用System.gc()並不是一個解決方案,因爲Java很有能力管理自己的內存。 – Kayaman