問題描述
假設我有一個長時間運行的循環:
Let's say I have a long running loop:
// Let's say this loop takes 10 seconds to execute
for(let i = 0; i <= 1000000; ++i) {
const garbage = { i };
// some other code
}
垃圾收集器可以在循環期間運行,還是只能在應用空閑時運行?
Can the garbage collector run during the loop, or it can only run when the application is idle?
我沒有找到任何與此相關的文檔,但是因為 Node.js 具有理論上禁用 GC 的 --nouse-idle-notification
,讓我認為 GC 僅在以下情況下運行發送空閑通知(當主線程不忙時).
I didn't find any documentation related to this, but because Node.js has the --nouse-idle-notification
which in theory disables GC, makes me think that the GC only runs when the idle notification is sent (when the main thread is not busy).
我之所以問這個問題是因為我的循環有時會出現執行時間峰值,并且想知道 GC 是否有可能在循環期間運行,從而導致延遲峰值.
I am asking this because my loop sometimes has spikes in execution time and want to know if it's possible that the GC might run during the loop, resulting in the lag spike.
推薦答案
V8 開發者在這里.簡短的回答是 GC 可以隨時運行,并且會在需要時運行.
V8 developer here. The short answer is that the GC can run at any time and will run whenever it needs to.
請注意,GC 是一個相當復雜的系統:它執行多個不同的任務,并且大部分以增量步驟和/或與主線程同時執行.特別是,每次分配都會觸發一些增量 GC 工作.(這意味著通過非常小心地避免所有分配,您可以構建在運行時不會導致 GC 活動的循環;但循環不會積累無法收集的垃圾——除非您的內存中有泄漏當然是代碼,其中對象無意中保持可訪問性.)
Note that the GC is a fairly complex system: it performs several different tasks, and does most of them in incremental steps and/or concurrently with the main thread. In particular, every allocation can trigger a bit of incremental GC work. (Which implies that by very carefully avoiding all allocations, you can construct loops that won't cause GC activity while they run; but it's never the case that loops accumulate garbage that can't get collected -- unless you have a leak in your code of course, where objects are unintentionally being kept reachable.)
垃圾收集器可以在循環期間運行,還是只能在應用空閑時運行?
Can the garbage collector run during the loop, or it can only run when the application is idle?
它絕對可以并且將在循環期間運行.
It absolutely can and will run during the loop.
Node.js 有 --nouse-idle-notification 理論上禁用 GC
Node.js has the --nouse-idle-notification which in theory disables GC
不,它沒有.沒有辦法禁用 GC.該標志禁用了觸發 GC 活動的一種特定機制,但這僅意味著 GC 將由其他機制觸發.
No, it does not. There is no way to disable GC. That flag disables one particular mechanism for triggering GC activity, but that only means that GC will be triggered by other mechanisms.
GC 只在發送空閑通知時運行(當主線程不忙時)
the GC only runs when the idle notification is sent (when the main thread is not busy)
不,我們的想法是在空閑時間運行一些額外個 GC 周期,以便在應用程序不忙時節省一些內存.
No, the idea is to run some extra GC cycles when there is idle time, to save some memory when the application is not busy.
我的循環有時會出現執行時間峰值,想知道 GC 是否有可能在循環期間運行,從而導致延遲峰值
my loop sometimes has spikes in execution time and want to know if it's possible that the GC might run during the loop, resulting in the lag spike
可能是這樣.它也可能與函數的優化或去優化有關.或者它可能是其他原因——例如,操作系統中斷了您的進程或將其分配給另一個 CPU 內核,或數百個其他原因.計算機是復雜的機器;-)
That could be. It could possibly also have to do with optimization or deoptimization of the function. Or it could be something else -- the operating system interrupting your process or assigning it to another CPU core, for example, or hundreds of other reasons. Computers are complex machines ;-)
如果您將變量設置為 null -- 垃圾收集會立即完成
if you set a variable to null -- garbage collection is done immediately
不,不是.垃圾收集永遠不會立即完成(至少在 V8 中不會).
No, it is not. Garbage collection is never done immediately (at least not in V8).
這篇關于主線程忙時可以進行垃圾收集嗎?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!