TCL'exec'的高分辨率時間軸行爲是什麼? 我知道一個'fork'命令將被使用,它將首先創建一個進程的內存映像的副本,然後繼續。TCL的時間解析內存佔用量exec
這是我的問題的動機:
一位用戶給了我下面的觀察。一臺64 GB的機器具有基於TCL的工具界面,使用60GB內存。 (讓我們假設交換很小)。在TCL提示符下,他給出了'exec ls',並且該進程因內存錯誤而崩潰。
您的洞察力非常感謝。 謝謝, Gert
TCL'exec'的高分辨率時間軸行爲是什麼? 我知道一個'fork'命令將被使用,它將首先創建一個進程的內存映像的副本,然後繼續。TCL的時間解析內存佔用量exec
這是我的問題的動機:
一位用戶給了我下面的觀察。一臺64 GB的機器具有基於TCL的工具界面,使用60GB內存。 (讓我們假設交換很小)。在TCL提示符下,他給出了'exec ls',並且該進程因內存錯誤而崩潰。
您的洞察力非常感謝。 謝謝, Gert
exec
命令將在內部調用fork()
系統調用。這通常是可以的,但是當操作系統被配置爲不能交換並且原始的Tcl進程非常大時(或者如果有很小的空間,這取決於當然的實際情況),可能會耗盡內存。
的想法,我有減少內存使用情況,其一是使用vfork()
(通過修補tclUnixPipe.c
;您可以在makefile,使定義USE_VFORK
,我不知道爲什麼沒有被更廣泛地使用)或(之前創建一個幫助程序大量的內存使用)將代表您的主進程執行exec
s。以下是如何做後者的選項:
# This is setup done at the start
set forkerProcess [open "|tclsh" r+]
fconfigure $forkerProcess -buffering line -blocking 0
puts $forkerProcess {
fconfigure stdout -buffering none
set tcl_prompt1 ""
set tcl_prompt2 ""
set tcl_interactive 0
proc exechelper args {
catch {exec {*}$args} value options
puts [list [list $value $options]]
}
}
# TRICKY BIT: Yield and drain anything unwanted
after 25
read $forkerProcess
# Call this, just like exec, to run programs without memory hazards
proc do-exec args {
global forkerProcess
fconfigure $forkerProcess -blocking 1
puts $forkerProcess [list exechelper {*}$args]
set result [gets $forkerProcess]
fconfigure $forkerProcess -blocking 0
while {![info complete $result]} {
append result \n [read $forkerProcess]
}
lassign [lindex $result 0] value options
return -options $options $value
}
發現此評論:「然而,對於包括Linux在內的大多數當前的內核,由於fork實現的方式,vfork的主要優點已經消失,而不是在執行fork時複製整個映像,而使用寫入時複製技術「。 所以它在一定程度上取決於操作系統。 –
@BradLanam你會這麼認爲,但事實證明,實際的重複成本仍然是一個實質性的問題。我更多地使用Java應用程序(使用管道很煩人)看到了這一點,但症狀非常明顯。 OTOH,vfork的問題在於,由於更爲普遍的線程化,父進程現在不太可能停下來等待。 –
如果系統沒有提交可用於寫入時複製頁面的內存,則對fork()的調用將失敗。使用寫入時複製有助於提高性能,但不是大小。啓用overcommit後,Linux將承諾比真正退出的更多內存(DRAM +交換)。但如果耗盡,內存管理器將像聯合航空公司的保安一樣進來,並移除正在運行的進程。 –
好問題! _Tricky_問題也。 –