深刻淺出Node(5) 內存控制

一)V8垃圾回收機制javascript

  1.1 V8的內存限制java

  1.2 V8垃圾回收機制  node

二) 高效使用內存算法

  2.1 內存空間的釋放數組

  2.2 使用堆外內存瀏覽器

  2.3 合理使用內存防止內存泄漏緩存

    2.3.1 慎將內存當緩存服務器

    2.3.2 關注隊列狀態閉包

  2.3 大內存應用函數

一)V8垃圾回收機制

  Node使用的是Chrome的V8引擎執行javascript,因爲運行在瀏覽器和服務端的場景不一樣,瀏覽器中網頁的運行時間較短,隨着網頁的關閉,相應的內存就會被回收,因此對精細的內存的管理需求度不高,可是在服務器端因爲程序處於長時間運行中,爲了達到高性能的服務端程序,就須要良好的垃圾回收策略和管理策略(機器和咱們自己的控制) 良好的管理策略能更好的使垃圾回收運行,垃圾回收是影響性能的因素之一

  V8的內存限制

  因爲V8在內存回收算法的使用的考慮下,V8給系統分配使用的內存是存在必定的限制的

  V8垃圾回收機制

  在垃圾回收機制上,V8主要根據內存中對象在內存中的特徵,對內存中的對象進行分區的管理.如下爲V8的堆內存的劃分

在新生區的內存空間中,因爲新生區內存對象的特徵是生存週期短,這部分採用Cheney算法.Cheney算法是一種採用複製方式實現的垃圾回收算法,它將新生代內存空分爲兩個區域:

處於使用狀態的From區域和處於閒置狀態的To區域.在分配對象的時候,會如今From區域中進行對象的分配,在進行垃圾回收的時候,將From區域中存活的對象copy到To區域而且將From區域和To區域進行角色互換.

當一個對象在進行屢次複製仍然存活,它就會被認爲是存活週期較長的對象,它就會被轉移到老生區域中.對象重新生區域移動到老生區域的過程稱爲晉升. 晉升主要有兩個條件:

  1. 一個對象時候經歷過Scavenge回收(也就是新生區域的垃圾回收)
  2. To空間的內存佔比(當To區域已經使用了25%的時候,從From區域複製的對象會直接晉升到老生區域.由於To區域會在接下來轉換爲From區域供新的內存的分配,須要預留合適大小的空間)

在老生區域主要採用Mark-sweep 和Mark-Compact 和 Incremental Marking等多種方式結合的方式來達到對老生區進行整理的目的

  • Mark-sweep 標記清除 主要分爲標記和清除 在標記階段,垃圾回收器會標記活着的對象,在清除階段會清除沒有被標記的對象
  • Mark-Compact 標記整理  它是在標記清除的基礎上的,在進行標記的過程當中,將活着的對象往一側進行移動,這樣就消除了內存的間隙,方便後續內存空間的分配
  • Incremental Marking 增量標記 在進行標記的時候,須要將應用程序的邏輯進行暫停,因此產生了增量標記,每次只標誌部分,在讓位出時間來執行應用程序.

 二)高效使用內存

  2.1 內存空間的釋放

  變量是引用的狀況下須要主動的釋放內存,例如對引用進行從新的賦值,這樣在垃圾回收器運行的時候,就會主要回收內存. 

  閉包是外部做用域訪問內部做用域中變量的方法,在使用完閉包後,要注意中間函數的釋放

  2.2 使用堆外內存

  Buffer對象的內存分配不通過V8的內存分配機制,因此在處理文件I/O的時候可使用Buffer來達到對堆外內存的使用

  2.3 合理使用內存防止內存泄漏

  形成內存泄漏的緣由是咱們的操做使得本應在垃圾回收中被回收的內存沒法被回收,變成老生區對象.主要有如下幾個緣由

  • 緩存
  • 隊列消費不及時
  • 做用域未釋放

2.3.1 慎將內存當緩存

  當咱們將一個對象常駐內存中做爲緩存使用的時候(老生區),垃圾回收算法每次都會對它進行操做,這就致使垃圾回收在作無用功而且咱們對這個緩存對象的大小不作控制的時候,還可能會致使它佔用過大的內存空間,致使進程的退出,而且內存做爲緩存這種方案沒法再各個進程間進行共享,解決方案是使用緩存軟件,他們擁有良好的管理策略,能更好的提高應用的性能.

2.3.2 關注隊列狀態

  在使用隊列(數組)來完成特殊的任務請求的時候,當任務的消耗低於生產的時候,就會形成堆積,產生內存泄漏.解決方案是設置警告或者超時響應等

  2.4 大內存應用

  對於大內存應用,例如讀取大的文件,可使用node中的stream模塊而且它繼承了event模塊.

相關文章
相關標籤/搜索