js內存管理系列篇一:內存分析

說在前面

我是web光明頂一期的學生,本文是對深究JS原理這個階段的分析。

在js裏面,內存的概念大都被忽略了,大家都知道js是門高級語言,有自動的垃圾回收機制,所以很多人理所當然的覺得這個事情是不需要我們管的,那麼你就大錯特錯了。

像C語言這樣的底層語言一般都有底層的內存管理接口,比如 malloc()和free()。相反,java,JavaScript是在創建變量(對象,字符串等)時自動進行了分配內存,並且在不使用它們時“自動”釋放。 釋放的過程稱爲垃圾回收。這個“自動”是混亂的根源,並讓JavaScript(和其他高級語言)開發者錯誤的感覺他們可以不關心內存管理。那麼,就存在了很大一個誤區:我們以爲我們壓根就不用管內存這一塊,所以一直都沒注意,所以會導致一系列問題,比如內存泄漏。

在這裏插入圖片描述

日常碰到的問題

1. 問題一
寫了一個for循環,不小心寫成了個死循環,發現瀏覽器卡死了,爲什麼?這個就是因爲不停的循環,變量一直在遞增。把內存耗沒了。可能大家還不知道什麼問題,你都找不到問題在哪。你還以爲是下小電影的時候把電腦搞中毒了。

2.問題二
寫遊戲程序的時候,這個內存問題尤爲突出,如果發生了卡頓或者延遲,這個很大機率就是內存不足的問題,我們可能定義了很多全局變量,或者閉包,使用完之後卻沒有回收,那麼它將一直存在於內存中,甚至發生內存泄漏。

3.問題三
喜歡看鬥魚直播或其它直播的朋友,大家是不是有碰到過這個問題?頁面看久了忽然崩掉了,需要重新刷新,產生這種問題的原因可能有兩個,1是內存持續增加沒有去清理,崩掉了。2是flash裏的bug 產生的內存泄露。

由此可見,內存是和性能直接相關的,是非常重要的一環。
那我們就來講一講內存

內存模型(堆與棧)

js中並沒有嚴格意義上區分棧內存與堆內存。因此我們可以粗淺的理解爲js的所有數據都保存在堆內存中。但是在某些場景,我們仍然需要基於堆棧數據結構的思路進行處理。

那麼先來講一講它的內存空間存儲原理

在這裏插入圖片描述

爲什麼要把它類比成乒乓球盒子?

這種乒乓球的存放方式與棧中存取數據的方式是一樣的。處於盒子中最頂層的乒乓球c,它一定是最後被放進去,但可以最先被使用。而我們想要使用底層的乒乓球I,就必須將上面的4個乒乓球取出來,讓乒乓球1處於盒子頂層。這就是棧空間先進後出,後進先出的特點。圖中已經詳細的表明了棧空間的存儲原理。

隊列與堆棧

隊列: 是一種支持先進先出(FIFO)的集合,即先被插入的數據,先被取出
堆棧: 是一種支持後進先出(LIFO)的集合,即後被插入的數據,先被取出

js數組實現隊列和堆棧的功能

 //隊列 先進先出
 let arr = new Array();
  arr.unshift(1);
  arr.unshift(2);
  arr.unshift(3);
  arr.pop();
  console.log(arr);
  
  //堆棧 先進後出
  let arr2 = new Array();
  arr2.push(1);
  arr2.push(2);
  arr2.push(3);
  arr2.pop();
  console.log(arr2);

隊列應用場景

比如說我們常用的QQ 它有一個回收機制大家知道吧,當長時間未登錄的時候 就收回去 刪掉這個用戶 重新拿出來賣錢(一般是靚號) 美滋滋,那肯定是先排序,看誰未登錄的時間最長,就先把它幹掉 是不是 不可能是我上一秒剛登陸和個靚妹聊天 下一秒就把我幹掉了 那我還不報警
這個時候就用隊列方法 從前往後面刪 我們的數據庫存了用戶 當庫存不下了 也是這麼操作的

堆棧應用場景

比如說我們做了一個樓盤預售活動 名額100,報名200個,這個時候也就是從後往前刪,先報名的保留。後面報名的逐個刪除。

內存分配

這是兩道道關於內存面試題,當我進行如下操作時,這時候,b是多少?

 let a = 10;
 let b = a;
 b = 20;

在變量對象中的數據發生複製行爲時,系統會自動爲新的變量分配一個新值。給它新建一塊內存空間
let b = a執行之後,a與b雖然值都等於10,但是他們其實已經是相互獨立互不影響的值了。具體如圖。所以我們修改了b的值以後,a的值並不會發生變化。
這是基本數據類型的相關操作。
在這裏插入圖片描述
那麼如果是這樣的情況呢?引用類型,這時候的obj.aa爲多少?

  let obj = {aa:20,bb:30};
  let obk = obj;
   obk.aa = 10;

通過let obk = obj;執行一次複製引用類型的操作。引用類型的複製同樣也會爲新的變量自動分配一個新的值保存在變量對象中,
但不同的是,這個新的值,僅僅只是引用類型的一個地址指針。
當地址指針相同時,儘管他們相互獨立,但是在變量對象中訪問到的具體對象實際上是同一個。因此當我改變obk時,obj也發生了變化。這就是引用類型的特性。如圖所示。
在這裏插入圖片描述
本文就到這裏了,如果對你有幫助,歡迎點贊評論與轉發,如果有錯誤之處,敬請指出。
我們前端現在交流都在一個叫Web光明頂的公衆號社區中,在這裏也認識到了很多一起學習的小夥伴和技術大咖。
大家對前端感興趣的,也可以關注下這個公衆號,內附有大量前端乾貨分享包括前端簡歷庫關鍵是還不收費。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章