2013-03-08 141 views
1

我正在處理的應用程序嵌入V8進行腳本編寫。爲了節省內存,我希望在不需要時關閉腳本組件,但由於某些原因,內存永遠不會返回到操作系統。如何釋放V8聲明的內存?

這裏是我的嘗試:

1.調用Dispose()上的持久性上下文處理

context.Dispose(); 

2.強制垃圾收集

while (!v8::V8::IdleNotification()); 

無的這對進程內存使用有任何顯着的影響。我可以清楚地看到腳本聲稱內存時的情況,但它不會再次下降。

我正在用ps -o rss確定進程內存使用情況。我知道,找出一個進程使用的內存在沒有探查器的情況下實際上是不可能的,但我相信當V8放開內存時rss應該下降。

+0

http://stackoverflow.com/questions/1421491/does-calling-free-or-delete-ever-release-memory-back-to-the-系統 – congusbongus 2013-03-08 11:56:20

+0

Ouch。必須調查一下。如果有人已經解決了V8的問題,我仍然會感興趣 - 但我能想到的唯一解決方案是在分叉進程中加載​​v8並殺死那個。 – futlib 2013-03-08 12:46:46

+0

是的,這確實發生在一個簡單的C程序:(仍然希望有關如何使操作系統回收內存的建議。 – futlib 2013-03-08 16:10:18

回答

0

即使您的應用程序正確釋放了內存,操作系統也可能不會回收內存(例如,出於性能原因)。應用程序堆可能還會佔用內存,以防您快速重新使用它。無論哪種方式,如果你確定你沒有泄漏(嘗試類似valgrind的東西),我不會擔心它。

+0

用這個試驗了一下,它感覺它有點神祕,如果我分配100 MB的內存一個小小的C程序,內存永遠不會回收,直到程序退出。如果我分配500 MB,它幾乎立即回收。任何想法,如果我可以強制操作系統回收它 – futlib 2013-03-08 16:09:41

+0

我猜你在實驗中越過在某種程度上,操作系統和/或應用程序堆庫「決定」它有足夠的內存以保證將其返回到系統池,但我並不知道影響這些決策的標準方法......這是一種實現權衡。例如,如果你繼續分配和釋放100MB循環中的一次又一次呢? – mark 2013-03-08 18:11:11

0

剛剛花了幾個小時與此搏鬥,最終不得不深入V8的api.cc。

將V8引腳變爲快速重用的全局對象模板的最後一個實例(可以是原始ObjectTemplate或從FunctionTemplate派生的代理)。當試圖強制GC刷新時,這是非常混亂的。解決方法是分配新的虛擬上下文(使用與您嘗試刷新的上下文相同的模板)。

static void do_gc() 
{ 
    { 
    Isolate *i = Isolate::GetCurrent(); 
    HandleScope h(i); 
    Handle<Context> c = Context::New(i); // Default contexes 
    Handle<Context> c = Context::New(i, 0, objtemplate); // With custom object 
    Handle<Context> c = Context::New(i, 0, fntemplate->InstanceTemplate()); // With proxy 
    } 
    while (!v8::V8::IdleNotification()); 
} 

要查看使用上下文https://github.com/katlogic/lv8/blob/344353dac702901c917a4c05438252121c527ab3/lv8.cpp#L755