當前位置:首頁 » 網頁前端 » 前端如何垃圾回收
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

前端如何垃圾回收

發布時間: 2023-03-06 11:26:47

『壹』 談談垃圾回收機制方式內存管理

1、原理

js按照固定的時間間隔找到不在繼續使用的變數,釋放其佔用的內存。

 

2.實現方式

(1)標記清除

垃圾收集器給存儲在內存上的所有變數都加上標記;

之後,去掉環境中的變數以及被環境引用變數的標記;

之後,被加上標記的變數就是准備刪除的變數(原因是環境中的變數無法訪問到這些變數了)。 

目前,IE、firefox、opera、chrome和Safari瀏覽器都是標記清除的垃圾回收策略,只是回收時間間隔不一樣。

 

(2)引用計數

原理:記錄每個變數被引用的次數。釋放引用計數為0的變數所佔用的內存。

IE9 將BOM和DOM對象轉換成了真正的js對象。

 

3、管理內存

背景:分配給瀏覽器的可用內存通常會比桌面應用程序少。

因此,如何使用最少的內存讓頁面獲得最優的性能,就需要考慮管理內存。

一個比較好的做法是:解除引用,即不再使用的變數設置為null。

『貳』 如何完善垃圾分類處理,有哪些建議

垃圾分類的處理,有前端和後端處理
所謂前端,即居民對於生活垃圾分類;後端是指各分類垃圾桶中垃圾的處理方式。
垃圾分類,重在源頭,即垃圾分類意識的培養。所以完善垃圾分類前端處理,主要是針對垃圾分類的主力軍進行垃圾分類的習慣養成。各社區可通過成立工作小組、開展基礎調研、確定轄區工作方案、落實宣傳培訓、配置分類設備、廣泛宣傳告知、落實值守指導、定期分析評價、平穩引導過渡、建立長效機制等步驟開展垃圾分類工作。
當然,如果您還有任何不明白的,可以了解一下凈界傳媒,旗下「分類西遊」是專注垃圾分類領域的活動策劃品牌。擁有多年垃圾分類實戰經驗,利用公益活動、教育游學、展覽展會、知識競賽、文藝匯演、網路直播、線上互動等多重宣傳推廣形式,引導群眾思想觀念,全面形成垃圾分類文化氛圍。
相信對推廣垃圾分類工作有很多好的方法推薦給您

『叄』 前端開發過程中遇到的內存泄露情況,如何解決的

1、定義和用法:

內存泄露是指一塊被分配的內存既不能使用,又不能回收,直到瀏覽器進程結束。C#和Java等語言採用了自動垃圾回收方法管理內存,幾乎不會發生內存泄露。我們知道,瀏覽器中也是採用自動垃圾回收方法管理內存,但由於瀏覽器垃圾回收方法有bug,會產生內存泄露。

2、內存泄露的幾種情況:

(1)、當頁面中元素被移除或替換時,若元素綁定的事件仍沒被移除,在IE中不會作出恰當處理,此時要先手工移除事件,不然會存在內存泄露。

『肆』 JVM垃圾收集機制

JVM垃圾回收機制是java程序員必須要了解的知識,對於程序調優具有很大的幫助(同時也是大廠面試必問題)。

要了解垃圾回收機制,主要從三個方面:

(1)垃圾回收面向的對象是誰?

(2)垃圾回收演算法有哪些?

(3)垃圾收集器有哪些?每個收集器有什麼特點。

接下來一一講解清楚:

一、垃圾回收面向的對象

也就是字面意思, 垃圾 回收嘛,重要的是垃圾,那什麼對象是垃圾呢,簡單來說就是無用的或已死的對象。這樣又引申出來什麼對象是已死的,怎麼判斷對象是否已死?

判斷對象是否已死有兩種演算法和對象引用分類:

(1)引用計數演算法:

也是字面意思,通過給對象添加引用計數器,添加引用+1,反之-1。當引用為0的時候,此時對象就可判斷為無用的。

優點:實現簡單,效率高。

缺點:無法解決循環引用(就是A引用B,B也引用A的情況)的問題。

(2)根搜索演算法(也就是GC Roots):

通過一系列稱為GC Roots的對象,向下搜索,路徑為引用鏈,當某個對象無法向上搜索到GC Roots,也就是成為GC Roots不可達,則為無用對象。

如果一個對象是GC Roots不可達,則需要經過兩次標記才會進行回收,第一次標記的時候,會判斷是否需要執行finalize方法(沒必要執行的情況:沒實現finalize方法或者已經執行過)。如果需要執行finalize方法,則會放入一個回收隊列中,對於回收隊列中的對象,如果執行finalize方法之後,沒法將對象重新跟GC Roots進行關聯,則會進行回收。

很抽象,對吧,來一個明了的解釋?

比如手機壞了(不可達對象),有錢不在乎就直接拿去回收(這就是沒實現finalize方法),如果已經修過但是修不好了(已經執行過finalize方法),就直接拿去回收站回收掉。如果沒修過,就會拿去維修店(回收隊列)進行維修,實在維修不好了(執行了finalize方法,但是無法連上GC Roots),就會拿去回收站回收掉了。

那什麼對象可以成為GC Roots呢?

1>虛擬機棧中的引用對象

2>本地方法棧中Native方法引用的對象

2>方法區靜態屬性引用對象

3>方法區常量引用對象

(3)對象引用分類

1>強引用:例如實例一個對象,就是即使內存不夠用了,打死都不回收的那種。

2>軟引用:有用非必須對象,內存夠,則不進行回收,內存不夠,則回收。例如A借錢給B,當A還有錢的時候,B可以先不還,A沒錢了,B就必須還了。

3>弱引用:非必須對象,只能存活到下一次垃圾回收前。

4>虛引用:幽靈引用,必須跟引用隊列配合使用,目的是回收前收到系統通知。

下面是java的引用類型結構圖:

(1)軟引用示例

內存夠用的情況:

運行結果:

內存不夠用的情況:

運行結果:

(2)弱引用示例結果:

無論如何都會被回收

(3)虛引用示例:

運行結果:

解釋:為什麼2和5的輸出為null呢,如下

3為null是因為還沒有進行gc,所以對象還沒加入到引用隊列中,在gc後就加入到了引用隊列中,所以6有值。

這個虛引用在GC後會將對象放到引用隊列中,所以可以在對象回收後做相應的操作,判斷對象是否在引用隊列中,可以進行後置通知,類似spring aop的後置通知。

二、垃圾回收發生的區域

垃圾回收主要發生在堆內存裡面,而堆內存又細分為 年輕代 老年代 ,默認情況下年輕代和老年代比例為1:2,比如整個堆內存大小為3G,年輕代和老年代分別就是1G和2G,想要更改這個比例需要修改JVM參數-XX:NewRatio,

比如-XX:NewRatio=4,那老年代:年輕代=4:1。而年輕代又分為Eden區,S0(Survivor From)和S1(Survivor To)區,一般Eden:S0:S1=8:1:1,如果想要更改此比例,則修改JVM參數-XX:SurvivorRatio=4,此時就是Eden:S0:S1=4:1:1。

在年輕代發生GC稱為Young GC,老年代發生GC成為Full GC,Young GC比Full GC頻繁。

解析Young GC:

JVM啟動後,第一次GC,就會把Eden區存活的對象移入S0區;第二次GC就是Eden區和S0一起GC,此時會把存活的對象移入S1區,S0清空;第三次GC就是Eden區和S1區進行GC,會把存活的對象移入S0區,如此往復循環15次(默認),就會把存活的對象存入老年區。

類似與如果有三個桶,編號分別為1(1號桶內的沙子是源源不斷的,就像工地上。你們沒去工地搬過磚可能不知道,但是我真的去工地上搬過啊),2,3。1裡面裝有沙子,需要將沙子篩為細沙。首先將桶1內的沙子篩選一遍過後的放置於桶2,第二次篩選就會將桶1和桶2裡面的沙子一起篩,篩完之後放到桶3內,桶2清空。第三次篩選就會將桶1和桶3的沙子一起篩選,曬完放到桶2內,桶3清空。如此往復循環15次,桶2或桶3裡面的沙子就是合格的沙子,就需要放到備用桶內以待使用。

上述中桶1就是Eden區,桶2就是S0區,桶3就是S1區。

三、垃圾回收演算法

三種,分別是復制演算法,標記-清除演算法,標記-整理演算法。

(1)復制演算法。

其會將內存區域分成同樣大小的兩塊,一塊用來使用,另外一塊在GC的時候存放存活的對象,然後將使用的一塊清除。如此循環往復。

適用於新生代。

優點:沒有內存碎片,缺點:只能使用一般的內存。

(2)標記-清除演算法。

使用所有內存區域,在GC的時候會將需要回收的內存區域先進行標記,然後同意回收。

適用於老年代。

缺點:產生大量內存碎片,會直接導致大對象無法分配內存。

(3)標記-整理演算法。

使用所有內存區域,在GC的時候會先將需要回收的內存區域進行標記,然後將存活對象忘一邊移動,最後將清理掉邊界以外的所有內存。

適用於老年代。

四、GC日誌查看

利用JVM參數-XX:+PrintGCDetails就可以在GC的時候列印出GC日誌。

年輕代GC日誌:

老年代GC日誌:

五、垃圾收集器

主要有四類收集器以及七大收集器

四類:

(1)Serial:單線程收集器,阻塞工作線程,它一工作,全部都得停下。

(2)Paralle:Serial的多線程版本,也是阻塞工作線程

(3)CMS(ConcMarkSweep):並行垃圾收集器,可以和工作線程一起工作。

(4)G1:將堆分成大小一致的區域,然後並發的對其進行垃圾回收。

怎麼查看默認的收集器呢?

用JVM參數-XX:+PrintCommandLineFlags,運行之後會輸出如下參數。可以看到,jdk1.8默認是Parallel收集器。

七大收集器:

(1)Serial:串列垃圾收集器,單線程收集器。用於新生代。用JVM參數-XX:+UseSerialGC開啟,開啟後Young區用Serial(底層復制演算法),Old區用Serial Old(Serial的老年代版本,底層是標記整理演算法)。

(2)ParNew:用於新生代,並行收集器。就是Serial的多線程版本。用JVM參數-XX:+UseParNewGC,young:parnew,復制演算法。Old:serialOld,標記整理演算法。-XX:ParallecGCThreads限制線程回收數量,默認跟cpu數目一樣。只是新生代用並行,老年代用串列。

(3)Parallel Scavenge:並行回收收集器。用JVM參數-XX:+UseParallelGC開啟,young:parallel scavenge(底層是復制演算法),old:parallel old(parallel的老年代版本,底層是標記整理),新生代老年代都用並行回收器。

這個收集器有兩個優點:

可控的吞吐量 :就是工作線程工作90%的時間,回收線程工作10%的時間,即是說有90%的吞吐量。

自適應調節策略 :會動態調節參數以獲取最短的停頓時間。

(4)Parallel Old:Parallel Scavenge的老年代版本,用的是標記整理演算法。用JVM參數-XX:+UseParallelOldGC開啟,新生代用Parallel Scavenge,老年代用Parallel Old

(5)CMS(ConcMarkSweep):並發標記清除。 底層是標記清除演算法,所以會產生內存碎片,同時也會耗cpu。 以獲取最短回收停頓時間為目標。-XX:+UseConcMarkSweep,新生代用ParNew,老年代用CMS。CMS必須在堆內存用完之前進行清除,否則會失敗,這時會調用SerialOld後備收集器。

初始標記和重新標記都會停止工作線程,並發標記和並發清除會跟工作線程一起工作。

(6)SerialOld:老年代串列收集器(以後Hotspot虛擬機會直接移除掉)。

(7)G1:G1垃圾收集器,演算法是標記整理,不會產生內存碎片。橫跨新生代老年代。實現盡量高吞吐量,滿足回收停頓時間更短。

G1可以精確控制垃圾收集的停頓時間,用JVM參數-XX:MaxGCPauseMillis=n,n為停頓時間,單位為毫秒。

區域化內存劃片Region,會把整個堆劃分成同樣大小的區域塊(1MB~32MB),最多2048個內存區域塊,所以能支持的最大內存為32*2048=65535MB,約為64G。

上圖是收集前和收集後的對比,有些對象很大,分割之後就是連續的區域,也即是上圖的Humongous。

上述理論可能有點乏味,下圖很清晰明了(某度找的)。

下面來一張整個垃圾回收機制的思維導圖(太大,分成兩部分)。

=======================================================

我是Liusy,一個喜歡健身的程序猿。

歡迎關注【Liusy01】,一起交流Java技術及健身,獲取更多干貨。