前端—初級階段5(16-20)

內容

1.內存泄漏與垃圾回收
2.cookie和session
3.單線程原理
4.上下左右居中的幾種實現。
5.BFC和IFC模型。

1、垃圾回收與內存泄漏

參考:內存控制css

1.垃圾回收

v8的垃圾回收策略主要基於分代式垃圾回收機制。按照對象的存活時間將內存的垃圾回收進行不一樣的分代,而後,分別對不一樣的分代的內存再進行高效的垃圾回收算法。在V8中,主要將內存分爲新生代和老生代兩代。新內存中的對象存活時間短,老內存中的對象存活時間長或常駐內存對象。html

clipboard.png

1)新生代垃圾回收算法scavenge算法java

新生代中的對象主要經過scavenge算法進行垃圾回收,其主要是採用cheney算法進行具體處理。web

cheney算法採用一種複製方式的垃圾回收算法,將堆內存一分爲二,只有一部分空間被使用稱爲From空間,另外一個處於閒置稱爲To空間。當進行分配對象的時候先在from空間分配,當進行垃圾回收時,會檢查from空間中的存活對象,將這些存活對象複製到to空間中,複製完成後From和to空間角色互換,清空to空間,在垃圾回收過程當中就是經過將存活對象在兩個空間中進行復制。ajax

  • 缺點: 只能使用一半的內存
  • 優勢: 只複製存活的對象,對於生命週期短的場景存活對象只佔小部分,因此時間效率高

當一個對象通過屢次複製依然存活時,就會被認爲是生命週期較長的對象,會被移入老生代內存中。算法

對於移入老生代內存有兩個條件:segmentfault

  • 對象已經通過新生代內存回收機制的回收依然存活
  • 複製到To空間的對象超過25%(爲何是25%?這個To空間接下來會成爲From空間並接受內存分配,若是佔比太高影響後續分配)

2)老內存垃圾回收算法Mark-Sweep & Mark-Compactapi

老內存中,大可能是不死的老對象,用scavenge算法又費力,又佔用空間,所以,採用了新的內存垃圾回收算法:Mark-Sweep & Mark-Compact。數組

Mark-Sweep 標記清掃瀏覽器

mark-sweep分爲標記和清除兩個階段,mark階段會遍歷堆,而後標記處活着的對象,sweep階段會清除沒有被標記的對象。mark-sweep只清理沒有標記的對象,在老內存中,死了的對象佔比較少,這也是這個算法高效的緣由。

mark-sweep的問題在於,每次sweep後,會存在內存碎片,這些不連續的內存碎片會佔有大量空間,所以,下一次複製大對象時,將會發現空間不夠,於是再次觸發垃圾回收,這個回收是沒必要要的,也浪費了cpu。爲了解決這個問題,增長了mark-compact算法。

mark-compact 標記整理和壓縮
mark-compact在整理過程當中,將活着的對象往一端移動,移動完成後,直接將另一端的內存清理掉。
由於mark-compact須要移動內存,所以,垃圾回收主要使用mark-sweep,在內存不夠時,纔會觸發一次mark-compact。
clipboard.png

這三種算法的比較:
clipboard.png

Incremental Marking
爲了不出現javaScript應用邏輯與垃圾回收器看到不一致的狀況,垃圾回收都要將應用邏輯停下來,這種行爲會形成停頓,在新生代垃圾回收過程當中由於存活對象比較少,即便停頓基本影響不大。在老生代垃圾回收中,一般存活對象較多,全堆垃圾回收的標記、清除、整理影響較大。
解決辦法:分批次進行,拆分紅許多小步,每進行一小步就讓邏輯運行一會。

clipboard.png

v8後續還引入了lazy sweeping與incremental compaction,同時還引入了,並行標記和並行清理,進一步的利用多核性能下降每次停頓的時間。

2.內存泄漏

內存泄漏的實質就是應當回收的對象由於意外沒有被回收,變成了常駐在老生代中的對象。
形成內存泄漏的主要緣由有:緩存、隊列消費不及時、做用域未釋放。

1)緩存
慎將內存當作緩存,一旦一個對象被當作緩存來使用,那它將會常駐在老生代中,這將致使垃圾回收在進行掃描和整理時,對這些對象作無用功。
v8內存是經過垃圾回收進行處理的,沒有過時策略,而真正的緩存是存在過時策略的。
緩存限制策略:將結果記錄在數組中,一旦超過數量,就以先進先出的方式進行淘汰。

2)閉包
閉包是經過中間函數進行間接訪問內部變量實現的一個功能,一旦變量引用這個中間函數,這個中間函數將不會釋放,同時也會使原始的做用域不會獲得釋放,做用域中產生的內存佔用也不會獲得釋放。除非再也不有引用,纔會逐步釋放。

2、cookie和session

參考:構建Web應用

1.cookie

http是一個無狀態的協議,現實中的業務倒是須要有狀態的,不然沒法區分用戶之間的身份。利用cookie記錄瀏覽器與客戶端之間的狀態。
cookie的處理分爲以下幾步:

  • 服務器向客戶服務發送cookie
  • 瀏覽器將cookie保存
  • 以後每次瀏覽器都會將cookie發送給服務器,服務器端再進行校驗

告知客戶端是經過響應報文實現的,響應的cookie值在set-cookie字段中,它的格式與請求中的格式不太相同,規範中對它的定義以下:

Set-Cookie: name=value; Path=/; Expires=Sun, 23-Apr-23 09:01:35 GMT; Domain=.domain.com;

name = value是必選字段,其餘爲可選字段。

可選字段 說明
path 表示這個cookie影響的路徑,當前訪問的路徑不知足該匹配時,瀏覽器則不發送這個cookie
Expires、Max-Age 用來告知瀏覽器這個cookie什麼時候過時的,若是不設置該選項,在關閉瀏覽器時,會丟失掉這個cookie,若是設置過時時間,瀏覽器將會把cookie內容寫入到磁盤中,並保存,下次打開瀏覽器,該cookie依舊有效。expires是一個utc格式的時間字符串,告知瀏覽器此cookie什麼時候將過時,max-age則告知瀏覽器,此cookie多久後將過時。expires會在瀏覽器時間設置和服務器時間設置不一致時,存在過時誤差。所以,通常用max-age會相對準確。
HttpOnly 告知瀏覽器不容許經過腳本document.cookie去更改這個cookie值,也就是document.cookie不可見,可是,在http請求的過程當中,依然會發送這個cookie到服務器端。
secure 當secure = true時,建立的cookie只在https鏈接中,被瀏覽器傳遞到服務器端進行會話驗證,若是http鏈接,則不會傳遞。所以,增長了被竊聽的難度。

cookie的性能影響

當cookie過多時,會致使報文頭較大,因爲大多數cookie不須要每次都用上,所以,除非cookie過時,不然會形成帶寬的浪費。

cookie優化的建議:

減少cookie的大小,切記不要在路由根節點設置cookie,由於這將形成該路徑下的所有請求都會帶上這些cookie,同時,靜態文件的業務不關心狀態,所以,cookie在靜態文件服務下,是沒有用處,請不要爲靜態服務設置cookie。
爲靜態組件使用不一樣的域名,cookie做用於相同的路由,所以,設定不一樣的域名,能夠防止cookie被上傳。
減小dns查詢,這個能夠基於瀏覽器的dns緩存來削弱這個反作用的影響(換用額外域名須要DNS查詢)。
cookie的不安全性
cookie能夠在瀏覽器端,經過調用document.cookie來請求cookie並修改,修改以後,後續的網絡請求中就會攜帶上修改事後的值。
例如:第三方廣告或者統計腳本,將cookie和當前頁面綁定,這樣能夠標識用戶,獲得用戶瀏覽行爲。

2.session

cookie存在各類問題,例如體積大、不安全,爲了解決cookie的這些問題,session應運而生,session只保存在服務器端,客戶端沒法修改,所以,安全性和數據傳遞都被保護。

如何將每一個客戶和服務器中的數據一一對應:

  • 基於cookie來實現用戶和數據的映射
  • 經過查詢字符串來實現瀏覽器端和服務器端數據的對應。它的原理是檢查請求的查詢字符串,若是沒值,會先生成新的帶值的URL。

安全性
session的口令保存在瀏覽器(基於cookie或者查詢字符串的形式都是將口令保存於瀏覽器),所以,會存在session口令被盜用的狀況。當web應用的用戶十分多,自行設計的隨機算法的口令值就有理論機會命中有效的口令值。一旦口令被僞造,服務器端的數據也可能間接被利用,這裏提到的session的安全,就主要指如何讓這一口令更加安全。

有一種方法是將這個口令經過私鑰加密進行簽名,使得僞造的成本較高。客戶端儘管能夠僞造口令值,可是因爲不知道私鑰值,簽名信息很難僞造。如此,咱們只要在響應時將口令和簽名進行對比,若是簽名非法,咱們將服務器端的數據當即過時便可,

將口令進行簽名是一個很好的解決方案,可是若是攻擊者經過某種方式獲取了一個真實的口令和簽名,他就能實現身份的僞造了,一種方案是將客戶端的某些獨有信息與口令做爲原值,而後簽名,這樣攻擊者一旦不在原始的客戶端上進行訪問,就會致使簽名失敗。這些獨有信息包括用戶IP和用戶代理。

3、單線程原理

1.單線程

JavaScript的單線程,與它的用途有關。做爲瀏覽器腳本語言,JavaScript的主要用途是與用戶互動,以及操做DOM。這決定了它只能是單線程,不然會帶來很複雜的同步問題。好比,假定JavaScript同時有兩個線程,一個線程在某個DOM節點上添加內容,另外一個線程刪除了這個節點,這時瀏覽器應該以哪一個線程爲準?
因此,爲了不復雜性,從一誕生,JavaScript就是單線程,這已經成了這門語言的核心特徵,未來也不會改變。

爲了利用多核CPU的計算能力,HTML5提出Web Worker標準,容許JavaScript腳本建立多個線程,可是子線程徹底受主線程控制,且不得操做DOM。因此,這個新標準並無改變JavaScript單線程的本質。

2.任務隊列

全部任務能夠分紅兩種,一種是同步任務(synchronous),另外一種是異步任務(asynchronous)。同步任務指的是,在主線程上排隊執行的任務,只有前一個任務執行完畢,才能執行後一個任務;異步任務指的是,不進入主線程、而進入"任務隊列"(task queue)的任務,只有"任務隊列"通知主線程,某個異步任務能夠執行了,該任務纔會進入主線程執行。

異步執行的運行機制以下。(同步執行也是如此,由於它能夠被視爲沒有異步任務的異步執行。)

  1. 全部同步任務都在主線程上執行,造成一個執行棧(execution context stack)。
  2. 主線程以外,還存在一個"任務隊列"(task queue)。只要異步任務有了運行結果,就在"任務隊列"之中放置一個事件。
  3. 一旦"執行棧"中的全部同步任務執行完畢,系統就會讀取"任務隊列",看看裏面有哪些事件。那些對應的異步任務,因而結束等待狀態,進入執行棧,開始執行。
  4. 主線程不斷重複上面的第三步

js引擎執行異步代碼而不用等待,是因有爲有 消息隊列和事件循環。

消息隊列:消息隊列是一個先進先出的隊列,它裏面存放着各類消息。
事件循環:事件循環是指主線程重複從消息隊列中取消息、執行的過程。

clipboard.png

3.事件循環進階:macrotask與microtask

JS中分爲兩種任務類型:macrotask和microtask,在ECMAScript中,microtask稱爲jobs,macrotask可稱爲task。

  • 宏任務(macrotask):setTimeout, setInterval, setImmediate, requestAnimationFrame,I/O, UI rendering。
  • 微任務(microtask):process.nextTick, Promise.then catch finally, MutationObserver,Object.observe 。

在掛起任務時,JS 引擎會將全部任務按照類別分到這兩個隊列中,首先在 macrotask 的隊列(這個隊列也被叫作 task queue)中取出第一個任務,執行完畢後取出 microtask 隊列中的全部任務順序執行;以後再取 macrotask 任務,周而復始,直至兩個隊列的任務都取完。

宏任務和微任務之間的關係:

clipboard.png

事件循環機制進一步補充

  • 主線程運行時會產生執行棧,棧中的代碼調用某些api時,它們會在事件隊列中添加各類事件(當知足觸發條件後,如ajax請求完畢)
  • 而棧中的代碼執行完畢,就會讀取事件隊列中的事件,去執行那些回調
  • 如此循環
  • 注意,老是要等待棧中的代碼執行完畢後纔會去讀取事件隊列中的事件

clipboard.png

參考

1.http://www.ruanyifeng.com/blo...
2.https://www.jianshu.com/p/f47...
3.實例

4、上下左右居中的幾種實現

https://blog.csdn.net/mars200...

5、BFC和IFC模型

1.BFC

BFC(Block Formatting Context)叫作「塊級格式化上下文」。
當一個元素設置了新的BFC後,就和這個元素外部的BFC沒有關係了,這個元素只會去約束本身內部的子元素。

1)BFC的佈局規則以下:

  • 內部的Box會在垂直方向,一個接一個地放置。
  • Box垂直方向的距離由margin決定。屬於同一個BFC的兩個相鄰Box的margin會發生重疊
  • 每一個盒子的左邊界都要緊靠包含容器的左邊界。即便存在浮動也是如此。除非這個元素本身造成了一個新的BFC。
  • BFC的區域不會與float box重疊。
  • BFC就是頁面上的一個隔離的獨立容器,容器裏面的子元素不會影響到外面的元素。反之也如此。
  • 計算BFC的高度時,浮動元素也參與計算

2)如何產生新的BFC

  1. 根元素;
  2. float不爲none;
  3. position爲absolute,fixed;
  4. display爲inline-block,table-cell,table-caption,flex;
  5. overflow不爲visible;

3)實際應用

  1. 清除浮動 例子
  2. margin摺疊問題
  3. 兩側佈局:左邊固定,右邊自適應
  4. 雙飛翼佈局 例子
  5. 張鑫旭:CSS深刻理解流體特性和BFC特性下多欄自適應佈局

2.IFC

IFC(Inline Formatting Content)叫作 行內格式化上下文。
1)規則

  • 盒子是水平一個接一個的排列,水平的margin,內邊距,邊框是能夠有的。
  • 垂直方向的對齊,多是底部對齊,頂部對齊,也多是基線對齊(這個是默認的);ps.這裏的盒子應該是指的內聯元素的盒子(span,strong等)和匿名內聯盒子(只有文本,沒有內聯元素包含,自動建立的),他們合稱內聯盒子,一個或者多個內聯盒子組成一個行框,行框的寬度由包含塊和出現的浮動決定的。
  • 行框中的內聯盒子的高度小於行框的高度時,內聯盒子的垂直方向的對齊方式取決於vertical-align屬性
  • 當一個行框水平不能容納內聯盒子時,他們將會在垂直方向上產生多個行框,他們上下一個挨着一個,可是不會重疊
  • 通常來講,行框的左邊界緊挨着包含容器的左邊界,行框的右邊界緊挨着包含容器的右邊界,(是兩個邊都緊挨着)。然而,浮動盒子可能存在於包含邊框邊界和行框邊界之間;
  • 多個內聯盒子的寬度小於包含他們的行框時,他們在水平方向的分佈取決於text-align屬性(默認是left)

2)主要影響IFC內佈局的css: 參考

  • font-size
  • line-height
  • height
  • vertical-aligin

容器的高度 height = line-height + vertical-align

相關文章
相關標籤/搜索