1.內存泄漏與垃圾回收
2.cookie和session
3.單線程原理
4.上下左右居中的幾種實現。
5.BFC和IFC模型。
參考:內存控制css
v8的垃圾回收策略主要基於分代式垃圾回收機制。按照對象的存活時間將內存的垃圾回收進行不一樣的分代,而後,分別對不一樣的分代的內存再進行高效的垃圾回收算法。在V8中,主要將內存分爲新生代和老生代兩代。新內存中的對象存活時間短,老內存中的對象存活時間長或常駐內存對象。html
1)新生代垃圾回收算法scavenge算法java
新生代中的對象主要經過scavenge算法進行垃圾回收,其主要是採用cheney算法進行具體處理。web
cheney算法採用一種複製方式的垃圾回收算法,將堆內存一分爲二,只有一部分空間被使用稱爲From空間,另外一個處於閒置稱爲To空間。當進行分配對象的時候先在from空間分配,當進行垃圾回收時,會檢查from空間中的存活對象,將這些存活對象複製到to空間中,複製完成後From和to空間角色互換,清空to空間,在垃圾回收過程當中就是經過將存活對象在兩個空間中進行復制。ajax
當一個對象通過屢次複製依然存活時,就會被認爲是生命週期較長的對象,會被移入老生代內存中。算法
對於移入老生代內存有兩個條件:segmentfault
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。
這三種算法的比較:
Incremental Marking
爲了不出現javaScript應用邏輯與垃圾回收器看到不一致的狀況,垃圾回收都要將應用邏輯停下來,這種行爲會形成停頓,在新生代垃圾回收過程當中由於存活對象比較少,即便停頓基本影響不大。在老生代垃圾回收中,一般存活對象較多,全堆垃圾回收的標記、清除、整理影響較大。
解決辦法:分批次進行,拆分紅許多小步,每進行一小步就讓邏輯運行一會。
v8後續還引入了lazy sweeping與incremental compaction,同時還引入了,並行標記和並行清理,進一步的利用多核性能下降每次停頓的時間。
內存泄漏的實質就是應當回收的對象由於意外沒有被回收,變成了常駐在老生代中的對象。
形成內存泄漏的主要緣由有:緩存、隊列消費不及時、做用域未釋放。
1)緩存
慎將內存當作緩存,一旦一個對象被當作緩存來使用,那它將會常駐在老生代中,這將致使垃圾回收在進行掃描和整理時,對這些對象作無用功。
v8內存是經過垃圾回收進行處理的,沒有過時策略,而真正的緩存是存在過時策略的。
緩存限制策略:將結果記錄在數組中,一旦超過數量,就以先進先出的方式進行淘汰。
2)閉包
閉包是經過中間函數進行間接訪問內部變量實現的一個功能,一旦變量引用這個中間函數,這個中間函數將不會釋放,同時也會使原始的做用域不會獲得釋放,做用域中產生的內存佔用也不會獲得釋放。除非再也不有引用,纔會逐步釋放。
參考:構建Web應用
http是一個無狀態的協議,現實中的業務倒是須要有狀態的,不然沒法區分用戶之間的身份。利用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和當前頁面綁定,這樣能夠標識用戶,獲得用戶瀏覽行爲。
cookie存在各類問題,例如體積大、不安全,爲了解決cookie的這些問題,session應運而生,session只保存在服務器端,客戶端沒法修改,所以,安全性和數據傳遞都被保護。
如何將每一個客戶和服務器中的數據一一對應:
安全性
session的口令保存在瀏覽器(基於cookie或者查詢字符串的形式都是將口令保存於瀏覽器),所以,會存在session口令被盜用的狀況。當web應用的用戶十分多,自行設計的隨機算法的口令值就有理論機會命中有效的口令值。一旦口令被僞造,服務器端的數據也可能間接被利用,這裏提到的session的安全,就主要指如何讓這一口令更加安全。
有一種方法是將這個口令經過私鑰加密進行簽名,使得僞造的成本較高。客戶端儘管能夠僞造口令值,可是因爲不知道私鑰值,簽名信息很難僞造。如此,咱們只要在響應時將口令和簽名進行對比,若是簽名非法,咱們將服務器端的數據當即過時便可,
將口令進行簽名是一個很好的解決方案,可是若是攻擊者經過某種方式獲取了一個真實的口令和簽名,他就能實現身份的僞造了,一種方案是將客戶端的某些獨有信息與口令做爲原值,而後簽名,這樣攻擊者一旦不在原始的客戶端上進行訪問,就會致使簽名失敗。這些獨有信息包括用戶IP和用戶代理。
JavaScript的單線程,與它的用途有關。做爲瀏覽器腳本語言,JavaScript的主要用途是與用戶互動,以及操做DOM。這決定了它只能是單線程,不然會帶來很複雜的同步問題。好比,假定JavaScript同時有兩個線程,一個線程在某個DOM節點上添加內容,另外一個線程刪除了這個節點,這時瀏覽器應該以哪一個線程爲準?
因此,爲了不復雜性,從一誕生,JavaScript就是單線程,這已經成了這門語言的核心特徵,未來也不會改變。
爲了利用多核CPU的計算能力,HTML5提出Web Worker標準,容許JavaScript腳本建立多個線程,可是子線程徹底受主線程控制,且不得操做DOM。因此,這個新標準並無改變JavaScript單線程的本質。
全部任務能夠分紅兩種,一種是同步任務(synchronous),另外一種是異步任務(asynchronous)。同步任務指的是,在主線程上排隊執行的任務,只有前一個任務執行完畢,才能執行後一個任務;異步任務指的是,不進入主線程、而進入"任務隊列"(task queue)的任務,只有"任務隊列"通知主線程,某個異步任務能夠執行了,該任務纔會進入主線程執行。
異步執行的運行機制以下。(同步執行也是如此,由於它能夠被視爲沒有異步任務的異步執行。)
js引擎執行異步代碼而不用等待,是因有爲有 消息隊列和事件循環。
消息隊列:消息隊列是一個先進先出的隊列,它裏面存放着各類消息。
事件循環:事件循環是指主線程重複從消息隊列中取消息、執行的過程。
JS中分爲兩種任務類型:macrotask和microtask,在ECMAScript中,microtask稱爲jobs,macrotask可稱爲task。
在掛起任務時,JS 引擎會將全部任務按照類別分到這兩個隊列中,首先在 macrotask 的隊列(這個隊列也被叫作 task queue)中取出第一個任務,執行完畢後取出 microtask 隊列中的全部任務順序執行;以後再取 macrotask 任務,周而復始,直至兩個隊列的任務都取完。
宏任務和微任務之間的關係:
事件循環機制進一步補充
1.http://www.ruanyifeng.com/blo...
2.https://www.jianshu.com/p/f47...
3.實例
https://blog.csdn.net/mars200...
BFC(Block Formatting Context)叫作「塊級格式化上下文」。
當一個元素設置了新的BFC後,就和這個元素外部的BFC沒有關係了,這個元素只會去約束本身內部的子元素。
1)BFC的佈局規則以下:
2)如何產生新的BFC
3)實際應用
IFC(Inline Formatting Content)叫作 行內格式化上下文。
1)規則
2)主要影響IFC內佈局的css: 參考
容器的高度 height = line-height + vertical-align