2013-12-14 32 views
0

我正在學習Javascript,並且在各種文本中,作者將使用標記和掃描gc從內存中釋放對象來說javascript。他們會說到如何設置值的變量引用爲null它將刪除對該值的引用,允許爲gc設置分配的空間。 This SO answer表示可以通過將變量包含的值設置爲null,然後將其設置爲undefined,從堆中有效地移除已分配的空間(如果我理解正確),可以刪除分配的內存和引用。有什麼方法可以防止Javascript gc儘可能少運行?

所以我的問題是這樣的:是否有可能以這種方式編寫JavaScript,你可以消除gc?

(如果它是特定的實現,我想知道是否有可能在v8,但如果這是可能的犀牛或其他JS實現,這將是巨大的使用過的)

通過像LLJS項目評審我的請求不是太無理,但我不完全確定內存模塊是如何做到的。

我一直覺得它有幫助,如果我解釋爲什麼我問這麼回事。我非常喜歡編譯器,我想編寫一個編譯爲js語言,利用類似於SML的靜態推斷類型系統。之所以我想寫自己的原因是因爲我想利用區域推理來確定對象和變量何時超出範圍(儘可能),並且在離開範圍時將其從堆中移除,從而儘可能地消除gc可能。這主要是一個研究項目(閱讀:因爲我可以),所以任何在javascript中的內存優化資源也將不勝感激!

編輯:我想另一種說法是:「是否可以用gc確定性地永遠運行(儘可能)來編寫js?如果是這樣,將涉及哪些技術? 「

我並不是爲delete本身看,因爲它標記刪除的元素,從而調用我想(試圖)避免,我很好奇,如果實施的gc會運行,如果我刪除所有引用(和值)與變量相關聯。

另外,改寫從SO參考答案:

x = foo; x = null; x;

爲X仍然在堆?

回答

0

這並不完全清楚你在找什麼。

標準的Javascript實現沒有辦法手動釋放內存。您可以使用delete運算符刪除屬性,但只是從該對象中刪除屬性。它甚至不釋放該屬性指向的任何內容(如果沒有其他引用,則留給垃圾收集)。

JavaScript是從頭開始設計的垃圾收集語言。只有當垃圾收集器運行並且垃圾收集器找到無法訪問的對象(例如沒有對仍在使用的對象的引用)時,它才從物理內存中釋放事物。該語言不包含釋放內存的命令。

有可能(在一些JS實現中)自己調用GC而不是等待JS引擎運行它,但它仍然使用GC來決定釋放什麼。


迴應您添加到答案中的其他內容。

爲了我所知,JavaScript只會在GC運行時清理一些東西。在此之前,對象被標記爲使得GC可以看到任何地方都沒有對它們的引用,但是在GC檢查並通知它之前,它們實際上不會被釋放。此外,函數作用域中的局部變量本身就是一種對象類型,在GC運行之前這些變量不會被釋放,並且注意到沒有對函數作用域的引用(在JS中,即使在函數作用域之後,閉包也可以保留對函數作用域的引用該功能已完成)。

所以,在你的代碼示例:

x = foo; x = null; x; 

x仍然活着,並且佔據了一些空間,因爲它仍然在範圍和代碼仍然可以達到它。它的內容將是null,它大概不會在變量本身之外佔用額外的空間,但是變量本身的空間不會被釋放,直到它所處的函數上下文被垃圾回收器引用爲空閒。


JS是垃圾收集語言。那時候事情實際上是從堆中解放出來的。語言中沒有任何指示可以在任何時候更快地釋放事物。

+0

因此,換句話說,如果找不到對該對象的其他引用,則使用delete和GC釋放內存。所以程序員可能會釋放實際上導致釋放內存的對象。 –

+0

@JaniHyytiäinen - 不是。 'delete'運算符僅用於從對象中刪除屬性或將數組元素置回'undefined'狀態。 'delete'不會爲變量做任何事情。對於那些,你將它們設置爲「null」或「undefined」。如果你想了解'delete',你可以閱讀[這篇文章](http://perfectionkills.com/understanding-delete/)。這是唯一可能的JavaScript開發人員刪除對象的引用。如果沒有其他引用該對象,GC將清理它。 – jfriend00

+0

謝謝,我更新了我的問題,我希望它澄清 – pensivearchitect

-2

delete關鍵字將觸發瀏覽器的垃圾回收。請注意,除非您取消對象引用,否則它會刪除整個對象鏈。

var o = {...}; 

delete o; 
+0

如果您想了解應該如何使用delete,請參閱[本文](http://perfectionkills.com/understanding-delete/)。它主要用於從對象中移除屬性。而且,使用它並不會觸發垃圾收集,而不是觸發垃圾收集。 – jfriend00

+0

這是一篇很棒的博文,jfriend00。儘管如此,我沒有在帖子中看到這與垃圾收集的關係。我在刪除一個對象的屬性之前編寫了代碼,該對象本身引用了許多其他對象,並且我注意到瀏覽器中存在一些暫停。它讓我覺得垃圾回收器會檢查被刪除的對象以釋放內存(以及處理器使用率的上升)。但是,我從來沒有發現任何證據支持這一點。只是軼事「呃,這是奇怪的......」的情況。 –

+0

我只是給了你那個鏈接,因爲你的回答使用了'delete'操作符。當GC運行完全取決於實現時,會因瀏覽器而異(它不是任何標準文檔的主題)。JS引擎通常會延遲GC,直到完成當前的執行線程,這樣可以避免干擾運行時性能,因此他們可以對上次運行的代碼執行一次掃描,而不是很多。但是,在執行過程中肯定會有一些條件。 – jfriend00

相關問題