XMLHttpRequest對象的生命周期是如何管理的?
當定義一個XMLHttpRequest對象,並設置完相應的回調然後發出請求後,就可能會跳出該對象的作用域了(比如當前的函數已返回),但是這個對象不會被當做垃圾回收掉,因為當收到回復時回調依然會被調用。那麼這個對象是如何被管理的呢?什麼時候才會被回收?什麼時候不會?為什麼要這樣設計?
還有就是Node.JS中的http.Server等類應該也是類似的(C++層對應的是HandleWrap,而非與之對應的ObjectWrap),是否和上面基於同樣的考慮?我看完Node.JS相關代碼,認為是C++對JavaScript的對象加了一個引用,從而導致不會被GC。這樣設計相對於把對象的生命周期管理完全交給JavaScript層來管理有什麼優點?
「認為是C++對JavaScript的對象加了一個引用,從而導致不會被GC」,你這個理解是不太正確的。
其實xhr對象沒有被回收很容易理解,那就是xhr對象本身肯定還存在某個地方,因為回調需要這個對象,否則要回調的時候到哪裡找?至於說保存它的程序是原生JS還是host環境並不重要——儘管在實現細節上會有很多不同,但是最終都要確保JS的語義。
另外,「把對象的生命周期管理完全交給JavaScript層來管理」,對象的生命周期管理是JS引擎的事情,而不是你的JS程序的事情。GC就是干這個的。
事件回調函數中event.target表示這個事件在哪個對象上觸發,可想而知,註冊事件回調函數的時候,JS引擎除了要保存事件回調函數,還要保存觸發這個事件的對象
引用自:XMLHttpRequest當然只涉及到一個高層的描述,實現細節應該參考具體的JS引擎An XMLHttpRequest object must not be garbage collected if its state is OPENED and the send() flag is set, its state is HEADERS_RECEIVED, or its state is LOADING, and one of the following is true:
It has one or more event listeners registered whose type is readystatechange, progress, abort, error, load, timeout, or loadend.
The upload complete flag is unset and the associated XMLHttpRequestUpload object has one or more event listeners registered whose type is progress, abort, error, load, timeout, or loadend.
If an XMLHttpRequest object is garbage collected while its connection is still open, the user agent must terminate the request.
推薦閱讀:
※為什麼 C++ 11 標準不加入 GC 功能呢?
※c++11標準 GC(垃圾回收)是否會使老代碼產生未定義行為?
※一個人基於OpenJDK實現GC的concurrent compact部分,以減少GC停頓,困難嗎?
※JVM堆內存很富足時,為什麼經常連續發生兩次full GC?
※CMS GC發生concurrent mode failure時,為什麼使用單線程的full GC?
TAG:前端開發 | JavaScript | Nodejs | GC垃圾回收計算機科學 |