亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

javascript閉包會造成內存泄漏嗎

發布時間:2021-11-17 15:05:20 來源:億速云 閱讀:108 作者:iii 欄目:web開發

本篇內容介紹了“javascript閉包會造成內存泄漏嗎”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

1. 標記清除

JavaScript  中最常用的垃圾收集方式是標記清除(mark-and-sweep)。垃圾收集器在運行的時候會給存儲在內存中的所有變量都加上標記(可以使用任何標記方式)。然后,它會去掉環境中的變量以及被環境中的變量引用的變量的標記。而在此之后再被加上標記的變量將被視為準備刪除的變量,原因是環境中的變量已經無法訪問到這些變量了。***,垃圾收集器完成內存清除工作,銷毀那些帶標記的值并回收它們所占用的內存空間。

2. 引用計數

引用計數(reference  counting)的含義是跟蹤記錄每個值被引用的次數。當聲明了一個變量并將一個引用類型值賦給該變量時,則這個值的引用次數就是1。如果同一個值又被賦給另一個變量,則該值的引用次數加1。相反,如果包含對這個值引用的變量又取得了另外一個值,則這個值的引用次數減1。當這個值的引用次數變成0  時,則說明沒有辦法再訪問這個值了,因而就可以將其占用的內存空間回收回來。這樣,當垃圾收集器下次再運行時,它就會釋放那些引用次數為零的值所占用的內存。

Netscape Navigator 3.0 是最早使用引用計數策略的瀏覽器,但很快它就遇到了一個嚴重的問題,請看下面這個例子:

function problem(){     var objectA = new Object();     var objectB = new Object();     objectA.someOtherObject = objectB;     objectB.anotherObject = objectA; }

說明:objectA 和objectB  通過各自的屬性相互引用,即這兩個對象的引用次數都是2,在采用標記清除策略的實現中,由于函數執行之后,這兩個對象都離開了作用域,因此這種相互引用不是個問題。但在采用引用計數策略的實現中,當函數執行完畢后,objectA  和objectB 還說明將繼續存在,因為它們的引用次數永遠不會是0。假如這個函數被重復多次調用,就會導致大量內存得不到回收。

為此,Netscape 在Navigator 4.0  中放棄了引用計數方式,然而引用計數導致的麻煩并未就此了結。IE9以前中有一部分對象并不是原生JavaScript 對象。例如,其BOM 和DOM  中的對象就是使用C++以COM(Component Object Model,組件對象模型)對象的形式實現的,而COM  對象的垃圾收集機制采用的就是引用計數策略。因此,即使IE 的JavaScript 引擎是使用標記清除策略來實現的,但JavaScript 訪問的COM  對象依然是基于引用計數策略的。換句話說,只要在IE 中涉及COM 對象,就會存在循環引用的問題。

比如:

var element = document.getElementById("some_element"); var myObject = new Object(); myObject.element = element; element.someObject = myObject;

DOM 元素(element)與一個原生JavaScript 對象(myObject)之間創建了循環引用。其中,變量myObject  有一個名為element 的屬性指向element 對象;而變量element 也有一個屬性名叫someObject  回指myObject。由于存在這個循環引用,即使將例子中的DOM 從頁面中移除,它也永遠不會被回收。

解決辦法:將變量設為null從而切斷變量與它此前引用的值之間的連接。

myObject.element = null;  element.someObject = null;

看完上面的內容,我來談正題。

閉包不會引起內存泄漏

由于IE9 之前的版本對JScript 對象和COM 對象使用不同的垃圾收集。因此閉包在IE  的這些版本中會導致一些特殊的問題。具體來說,如果閉包的作用域鏈中保存著一個HTML 元素,那么就意味著該元素將無法被銷毀請看例子:

function assignHandler(){     var element = document.getElementById("someElement");     element.onclick = function(){         alert(element.id);     }; }

以上代碼創建了一個作為element  元素事件處理程序的閉包,而這個閉包則又創建了一個循環引用。由于匿名函數保存了一個對assignHandler()的活動對象的引用,因此就會導致無法減少element  的引用數。只要匿名函數存在,element 的引用數至少也是1,因此它所占用的內存就永遠不會被回收

解決辦法前言已經提到過,把element.id 的一個副本保存在一個變量中,從而消除閉包中該變量的循環引用同時將element變量設為null。

function assignHandler(){     var element = document.getElementById("someElement");     var id = element.id;     element.onclick = function(){         alert(id);     };     element = null; }

“javascript閉包會造成內存泄漏嗎”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

建德市| 庄浪县| 城市| 宁都县| 兰西县| 长治县| 天峻县| 临武县| 沧州市| 利川市| 玛沁县| 东乡县| 昂仁县| 波密县| 宽甸| 黑山县| 开化县| 九龙县| 仲巴县| 喀什市| 娱乐| 称多县| 楚雄市| 武鸣县| 泰和县| 南丰县| 花莲市| 西充县| 泉州市| 岢岚县| 德保县| 三明市| 内江市| 敖汉旗| 米林县| 辉县市| 衡水市| 绥宁县| 子洲县| 阿拉善右旗| 通州区|