中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

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

JavaScript中內存泄漏的情況有哪些

發布時間:2023-04-27 10:13:37 來源:億速云 閱讀:112 作者:iii 欄目:開發技術

這篇文章主要介紹了JavaScript中內存泄漏的情況有哪些的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇JavaScript中內存泄漏的情況有哪些文章都會有所收獲,下面我們一起來看看吧。

    一、內存泄漏是什么

    內存泄漏(Memory leak)是再計算機科學中,由于疏忽或錯誤造成程序未能釋放已經不再使用的內存。

    并非指內存在物理上的消失,而是應用程序分配某段內存后,由于設計錯誤,導致在釋放該段內存之前就失去了對該段內存的控制,從而造成了內存的浪費。

    程序的運行需要內存。只要程序提出要求,操作系統或者運行時就必須供給內存。

    對于持續運行的服務進程,必須及時釋放不再用到的內存。否則,內存占用越來越高,輕則影響系統性能,重則導致進程崩潰。

    JavaScript中內存泄漏的情況有哪些

    在C語言中,因為是手動管理內存,內存泄露是經常出現的事情。

    char * buffer;
    buffer = (char*) malloc(42);
    // Do something with buffer
    free(buffer);

    上面是 C 語言代碼,malloc方法用來申請內存,使用完畢之后,必須自己用free方法釋放內存。

    這很麻煩,所以大多數語言提供自動內存管理,減輕程序員的負擔,這被稱為"垃圾回收機制"

    二、垃圾回收機制

    Javascript 具有自動垃圾回收機制(GC:Garbage Collecation),也就是說,執行環境會負責管理代碼執行過程中使用的內存

    原理:垃圾收集器會定期(周期性)找出那些不在繼續使用的變量,然后釋放其內存

    通常情況下有兩種實現方式:

    • 標記清除

    • 引用計數

    1、標記清除

    JavaScript最常用的垃圾收回機制

    當變量進入執行環境是,就標記這個變量為“進入環境“。進入環境的變量所占用的內存就不能釋放,當變量離開環境時,則將其標記為“離開環境“

    垃圾回收程序運行的時候,會標記內存中存儲的所有變量。然后,它會將所有在上下文中的變量,以及被在上下文中的變量引用的變量的標記去掉

    在此之后再被加上標記的變量就是待刪除的了,原因是任何在上下文中的變量都訪問不到它們了

    隨后垃圾回收程序做一次內存清理,銷毀帶標記的所有值并收回它們的內存

    代碼如下(示例):

    var m = 0,n = 19 // 把 m,n,add() 標記為進入環境。
    add(m, n) // 把 a, b, c標記為進入環境。
    console.log(n) // a,b,c標記為離開環境,等待垃圾回收。
    function add(a, b) {
      a++
      var c = a + b
      return c
    }

    2、引用計數

    語言引擎有一張"引用表",保存了內存里面所有的資源(通常是各種值)的引用次數。如果一個值的引用次數是0,就表示這個值不再用到了,因此可以將這塊內存釋放

    如果一個值不再需要了,引用數卻不為0,垃圾回收機制無法釋放這塊內存,從而導致內存泄漏

    代碼如下(示例):

    const arr = [1, 2, 3, 4];
    console.log('hello world');
    // arr = null

    上面代碼中,數組[1, 2, 3, 4]是一個值,會占用內存。變量arr是僅有的對這個值的引用,因此引用次數為1。盡管后面的代碼沒有用到arr,它還是會持續占用內存。

    如果需要這塊內存被垃圾回收機制釋放,只需要再次將arr設置為null,就解除了對數組[1,2,3,4]的引用,引用次數變為 0,就被垃圾回收了。

    小結

    有了垃圾回收機制,不代表不用關注內存泄露。那些很占空間的值,一旦不再用到,需要檢查是否還存在對它們的引用。如果是的話,就必須手動解除引用。

    三、常見的內存泄漏的情況

    1、意外的全局變量

    // 不設置定義變量的方法默認為var
    function foo(arg) {
        bar = "this is a hidden global variable";
    }
    // 另一種意外的全局變量可能由 this 創建:
    function foo() {
        this.variable = "potential accidental global";
    }
    // foo 調用自己,this 指向了全局對象(window)
    foo();

    上述使用嚴格模式,可以避免意外的全局變量。

    2、定時器造成的內存泄露

    var someResource = getData();
    setInterval(function() {
        var node = document.getElementById('Node');
        if(node) {
            // 處理 node 和 someResource
            node.innerHTML = JSON.stringify(someResource));
        }
    }, 1000);

    如果id為Node的元素從DOM中移除,該定時器仍會存在,同時,因為回調函數中包含對someResource的引用,定時器外面的someResource也不會被釋放

    3、閉包

    function bindEvent() {
      var obj = document.createElement('XXX');
      var unused = function () {
        console.log(obj, '閉包內引用obj obj不會被釋放');
      };
      obj = null; // 解決方法
    }

    維持函數內局部變量,使其得不到釋放

    4、沒有清理對DOM元素的引用

    const refA = document.getElementById('refA');
    document.body.removeChild(refA); // dom刪除了
    console.log(refA, 'refA'); // 但是還存在引用能console出整個div 沒有被回收
    refA = null;
    console.log(refA, 'refA'); // 解除引用

    5、事件監聽(addEventListener)

    包括使用事件監聽addEventListener監聽的時候,在不監聽的情況下使用removeEventListener取消對事件監聽

    關于“JavaScript中內存泄漏的情況有哪些”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“JavaScript中內存泄漏的情況有哪些”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。

    向AI問一下細節

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

    AI

    定兴县| 花莲县| 舞阳县| 青河县| 德格县| 渭源县| 烟台市| 油尖旺区| 定远县| 任丘市| 西华县| 仁怀市| 巴林右旗| 固始县| 陆川县| 陆良县| 呼图壁县| 黑山县| 灌南县| 太谷县| 阜阳市| 五大连池市| 高青县| 蚌埠市| 云霄县| 集贤县| 克拉玛依市| 谢通门县| 北流市| 沭阳县| 靖远县| 达尔| 莱阳市| 三河市| 宁远县| 桃园市| 五河县| 呈贡县| 东乡族自治县| 疏附县| 徐汇区|