成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

閉包會造成內存泄漏嗎?

開發 前端
在談內存泄漏這個問題之前先看看JavaScript的垃圾收集機制,JavaScript 具有自動垃圾收集機制,就是找出那些不再繼續使用的變量,然后釋放其占用的內存。為此,垃圾收集器會按照固定的時間間隔(或代碼執行中預定的收集時間)。常用的的方法有兩種,即標記清楚和引用計數。

[[174907]]

前言

在談內存泄漏這個問題之前先看看JavaScript的垃圾收集機制,JavaScript 具有自動垃圾收集機制,就是找出那些不再繼續使用的變量,然后釋放其占用的內存。為此,垃圾收集器會按照固定的時間間隔(或代碼執行中預定的收集時間)。常用的的方法有兩種,即標記清楚和引用計數。

1. 標記清除

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

2. 引用計數

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

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

  1. function problem(){ 
  2.     var objectA = new Object(); 
  3.     var objectB = new Object(); 
  4.     objectA.someOtherObject = objectB; 
  5.     objectB.anotherObject = objectA; 
  6.  

說明: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 對象,就會存在循環引用的問題。

比如:

  1. var element = document.getElementById("some_element"); 
  2. var myObject = new Object(); 
  3. myObject.element = element; 
  4. element.someObject = myObject;  

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

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

  1. myObject.element = null
  2.  
  3. element.someObject = null 

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

閉包不會引起內存泄漏

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

  1. function assignHandler(){ 
  2.     var element = document.getElementById("someElement"); 
  3.     element.onclick = function(){ 
  4.         alert(element.id); 
  5.     }; 
  6.  

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

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

  1. function assignHandler(){ 
  2.     var element = document.getElementById("someElement"); 
  3.     var id = element.id; 
  4.     element.onclick = function(){ 
  5.         alert(id); 
  6.     }; 
  7.     element = null
  8.  

總結:閉包并不會引起內存泄漏,只是由于IE9之前的版本對JScript對象和COM對象使用不同的垃圾收集,從而導致內存無法進行回收,這是IE的問題,所以閉包和內存泄漏沒半毛錢關系。

這篇文章里做了詳細的測試,有興趣的可以點擊查看

責任編輯:龐桂玉 來源: segmentfault
相關推薦

2022-05-09 14:09:23

多線程線程安全

2021-03-07 17:17:07

Java內存閉包

2025-04-01 05:22:00

JavaThread變量

2015-08-18 13:42:42

js作用域鏈變量

2022-04-07 07:41:18

String字符串內存泄漏

2024-01-22 09:51:32

Swift閉包表達式尾隨閉包

2021-06-02 07:57:48

內存管理

2023-07-11 08:46:38

閉包函數Rust

2024-03-11 08:22:40

Java內存泄漏

2023-12-18 10:45:23

內存泄漏計算機服務器

2012-02-22 21:28:58

內存泄漏

2021-02-21 16:21:19

JavaScript閉包前端

2025-02-11 08:00:00

閉包JavaScript開發

2019-07-17 15:45:24

Spark內存Java

2017-03-09 10:45:31

定義內存泄漏

2023-01-09 08:00:41

JavaScript閉包

2015-03-30 11:18:50

內存管理Android

2021-01-22 07:48:07

JavaScript 高階函數閉包

2024-11-26 00:45:29

free區域字段

2021-08-09 09:54:37

內存泄漏JS 阿里云
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 婷婷丁香在线视频 | 成人亚洲片 | 91人人视频在线观看 | 亚洲黄色一区二区三区 | 男女黄网站| 四虎伊人| 亚洲精品9999久久久久 | 午夜寂寞影院列表 | 久久av网站 | 色姑娘综合网 | 国产精品夜夜春夜夜爽久久电影 | 国产精品久久久久久久久污网站 | 欧美精产国品一二三区 | 国产日韩欧美在线 | 成人精品一区二区三区中文字幕 | 日韩中文一区二区三区 | 久久精品国产a三级三级三级 | 日韩一区二 | 成人国产免费视频 | 欧美精品一区二区免费 | 精品久久久久久久久久久院品网 | 在线观看视频一区 | www视频在线观看 | 九九九久久国产免费 | 精品一区二区三区在线视频 | 午夜爽爽爽男女免费观看 | 国产精品久久久久久久久久久久冷 | 欧美一级网站 | 亚洲久草| 久久精品美女 | 操操日| 日韩综合在线 | 日韩一区精品 | 成人精品免费视频 | 毛片一区二区三区 | 欧美日韩在线精品 | 国产专区在线 | 日韩在线视频一区 | 99精品在线| 好姑娘高清在线观看电影 | 精品国产乱码久久久久久蜜柚 |