2017-03-02 33 views
1

TCL'exec'的高分辨率時間軸行爲是什麼? 我知道一個'fork'命令將被使用,它將首先創建一個進程的內存映像的副本,然後繼續。TCL的時間解析內存佔用量exec

這是我的問題的動機:

一位用戶給了我下面的觀察。一臺64 GB的機器具有基於TCL的工具界面,使用60GB內存。 (讓我們假設交換很小)。在TCL提示符下,他給出了'exec ls',並且該進程因內存錯誤而崩潰。

您的洞察力非常感謝。 謝謝, Gert

+0

好問題! _Tricky_問題也。 –

回答

1

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 
} 
+0

發現此評論:「然而,對於包括Linux在內的大多數當前的內核,由於fork實現的方式,vfork的主要優點已經消失,而不是在執行fork時複製整個映像,而使用寫入時複製技術「。 所以它在一定程度上取決於操作系統。 –

+0

@BradLanam你會這麼認爲,但事實證明,實際的重複成本仍然是一個實質性的問題。我更多地使用Java應用程序(使用管道很煩人)看到了這一點,但症狀非常明顯。 OTOH,vfork的問題在於,由於更爲普遍的線程化,父進程現在不太可能停下來等待。 –

+0

如果系統沒有提交可用於寫入時複製頁面的內存,則對fork()的調用將失敗。使用寫入時複製有助於提高性能,但不是大小。啓用overcommit後,Linux將承諾比真正退出的更多內存(DRAM +交換)。但如果耗盡,內存管理器將像聯合航空公司的保安一樣進來,並移除正在運行的進程。 –