从javaScript数据类型开始了解垃圾回收机制
一、 javaScript數據類型
javaScript 數據類型分為:基本數據類型、引用數據類型
基本數據類型
分類:Number、String、Boolean、Null、Undefined、Symbol。
存儲地址:棧。
引用數據類型
分類:Object、Array、Function。
存儲地址:堆。
二、存儲地址
棧
特點:小、速度快、有序。
通常情況下,棧的內存空間不會設置很大(因為棧空間是用來存放執行上下文的,如果棧空間設置的很大,會影響切換執行上下文的速度),棧一般用于存儲一些 原始類型 的小數據。
堆
特點:大、速度慢、無序。
堆的內存空間很大,常用于存儲類似 引用類型 的這樣的大數據。
三、垃圾回收機制
棧內存如何回收
當函數在執行時,有一個記錄當前執行狀態的指針(ESP)指向它。
當此函數被執行結束后,ESP指針指向下一個執行函數。雖然此時上一個函數還存在于占內存中,但下一個函數的執行可能會覆蓋掉它。
堆內存如何回收
這里主要介紹:V8引擎的垃圾回收機制。
原理:
1、內存劃分
引擎將堆內存分為兩個部分:新生代、老生代
新生代:存放生存時間較短的對象 -------由副垃圾回收器回收。
老生代:存放生存時間較長的對象 -------由主垃圾回收器回收。
2、副垃圾回收器
副垃圾回收器將 新生代內存空間 分為兩個部分:對象區域 和 空閑區域。
新加入的對象都會被放入對象區域,當對象區域快滿的時候,執行一次回收。
注意:如果對象區域很大,每次清理的時間就會很長,所以對象區域一般都很小,但也很容易被放滿。所以經過兩次垃圾回收之后依然存活的對象會被放入老生代。
回收過程:副垃圾回收器對 對象 區域中的垃圾進行標記,標記完成之后,進入垃圾清理階段,并將活躍的對象移入空閑區域(這時候會出現許多內存不連續的空白區域),同時還會把他們有序的排列起來,這個排列的過程就相當于做了內存整理。執行完上述操作后,再將 對象區域 與 空閑區域 的的角色相調換。
3、主垃圾回收器
主要采用 標記清除法 進行垃圾回收。
標記:
從一組根元素開始,遞歸遍歷這組根元素,在遍歷過程中能夠被遍歷到的元素成為活動對象,沒有被遍歷到的元素則是垃圾數據。
清除:
問題1:因為主垃圾回收器主要用來回收內存區域大,存儲數據大的垃圾,所以如果對所有的垃圾數據依次清除,會帶來很多的內存碎片。
解決:標記整理(在標記的過程中,將所有活躍的對象都向一邊移動,最后清除掉邊界以外的垃圾)。
問題2:JavaScript 是運行在主線程之上的,一旦執行垃圾回收算法,都需要將正在執行的 JavaScript 腳本暫停下來,待垃圾回收完畢后再恢復腳本執行,非常的耗時。
解決:讓垃圾回收操作和js腳本交替執行(類似時間片)。
思考:閉包之所以會帶來內存泄漏的問題,主要是因為不能對其變量進行垃圾回收,如何解決這個問題呢?
答案:使用完內存變量后,將此變量指向null。
總結
以上是生活随笔為你收集整理的从javaScript数据类型开始了解垃圾回收机制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java高级特性——反射
- 下一篇: Cause: java.lang.Ill