Nodejs記憶體治理步驟詳解
這次帶給大家Nodejs記憶體治理步驟詳解,Nodejs記憶體治理的注意事項有哪些,下面就是實戰案例,一起來看一下。
s運作的宿主環境不同,對應的對記憶體治理的要求也不一樣,當宿主環境是瀏覽器時,由於網頁的運行時間短,且只運行在使用者的機器上(相當於分散式),即使記憶體使用過多或存在一定的記憶體洩漏,也不會對終端用戶產生太大的影響。當宿主環境程式伺服器(Node)時,情況就大不相同了,本身程式碼運行在固定的幾台機器(集中式)上,而且運行的時間是長時間運行,一旦記憶體治理不好出現了記憶體膨脹甚至是記憶體洩漏的情況的話,就會出現伺服器端回應時間變長甚至是服務crash的情況。
Nodejs是基於V8建構的,所以在Node中使用的JavaScript物件基本上(Buffer就不是)都是透過V8來進行分配和管理的。 V8在佔用記憶體大小上做了限制(64位元作業系統,單一Node進程可使用的最大堆記憶體大小約為1.5GB)。即使伺服器的記憶體很大,但是由於V8的這種限制,導致Node無法充分利用伺服器的資源。即便如此,為什麼V8要做這樣的限制呢?做這樣限制的原因其實是與垃圾回收機制相關,以1.5GB的垃圾回收堆內存堆為例,V8做一次小的垃圾回收需要50ms以上,做一次全量的垃圾回收甚至要1s以上,要知道垃圾回收過程中JavaScript執行緒是要處於暫停執行的狀態,太長的暫行時間對於後端服務的效能是會產生較大影響的,所以出於這方面考慮,V8對堆記憶體做了限制。即便如此,V8還是提供了可以自訂堆記憶體大小的方式(--max-old-pace-size),old-space代表老生代、new-space代表新生代。
node --max-old-space-size=xxx index.js //单位为MB // 之前还可以通过-max-new-space-size来定义新生代堆大小,现在已经不可以了
當由於記憶體洩漏導致伺服器一直頻繁重啟的時候,建議先調大堆內存大小來為定位問題爭取時間,畢竟服務響應慢總比直接返回錯誤頁對於用戶而言會更好接受一點。
為什麼需要老生代和新生代?
老生代和新生代其實是分代式垃圾回收機制裡面的不同的分代,因為沒有一種垃圾回收演算法能夠勝任所有的場景,不同的物件生存週期其實需要不同的回收策略才能達到最好的效果,所以V8採用分代式垃圾回收機制,降對象按的存活時間進行不同的分代,然後對不同分代(新生代、老生代)的內存施以更適合也更好的演算法。
新生代中的物件存活時間較短,而老生代中的物件存活時間較長甚至是常駐記憶體。基於此所以設計的新生代的記憶體普遍比老生代的記憶體小很多,V8中新生代最大記憶體是32M(64位元系統為例),老生代最大記憶體是1400MB。 V8實際使用的堆記憶體大小是新生代老生代所用記憶體總和(1432MB),但是V8最大值其實是比使用的記憶體對大小額外大了32M(1464MB)
#新生代如何做垃圾回收?
新生代的採用名為Scavenge的垃圾回收演算法。在Scavenge的具體實作中,主要採用了Cheney演算法,Cheney演算法透過將新生代堆一分為二,一個使用(From semispace),一個空閒(To semispace)。 建立物件的時候,現在From空間中進行分配,當需要進行垃圾回收時,就檢查From空間中的存活對象,然後將存活的對象拷貝到To空間,同時清空From空間,並將From和To互換,整個垃圾回收過程中就是存活物件在兩個seispace之間進行複製。對於生命週期短的場景存活對像在整個對像中佔比較小,所以Scavenge採用的是複製存活的對象,但是Scavenge只能利用堆內存一半的空間,這是典型的用空間換時間的體現。
当一个对象经过多次垃圾回收依然存活的话,就会被认为是生命周期较长的对象,一方面新生代堆比较小,另一方面重复复制生命周期长的对象也很没有效率,所以对于生命周期长的对象会被移到老生代中去。新生代对象移动到老生代有两个对象:1.对象是否是生命周期较长的对象(已经经历过垃圾回收)2.To空间使用占比是否超过了25%。限制25%的原因是由于垃圾回收完成后To会变成From,如果不做限制的话可能会出现From很快被用光的情况,出现频繁的垃圾回收,也会影响效率。
老生代如何做垃圾回收?
老生代由于存活对象占较大比重,不适合对存活对象进行操作,使用Scavenge算法就不太合适了,因此老生代采用了Mark-Sweep和Mark-Compact相结合的方式。
Mark-Sweep分为标记和清除两个阶段,在标记阶段遍历堆中所有对象,标记活着的对象,然后在清除阶段未被标记的对象将会被清除掉。Mark-Sweep解决了内存释放的问题但是由于没有像Scavenge那样复制对象的操作导致内存碎片化不连续。而Mark-Compact就是用来解决内存碎片化问题的。Mark-Compact会将存活的对象往一端移动,移动完成后直接清理掉边界外的内存,这样就有大段的连续可用内存了,但是由于涉及到对象的移动,因此Mark-Compact的速度要比Mark-Sweep慢了。V8主要使用Mark-Sweep,只有当空间不足以对新生代中今生过来的对象进行分配时才使用Mark-Compact。
垃圾回收过程中会导致应用程序暂停执行,由于新生代本身空间较小,且要复制的存活对象占比也少,因此即便执行全量垃圾回收也影响不大,但是老生代空间很大,存活对象也多,执行一次全量垃圾回收对于应用程序暂停会是一个比较长的时间,因此V8将老生的标记改成了增量更新的方式,使得标记和应用程序交替执行直到标记完成,然后垃圾回收再执行后面的清理工作。注意清理工作并不是增量的。
开发者可以指定强制垃圾回收吗?
答案是可以了,在启动node服务的时候使用--expose-gc flag
$ node --expose-gc file.js
这样全局对象上就有了执行垃圾回收的函数
global.gc();
推荐更安全的写法
function forceGC() if (global.gc) { global.gc(); } else { console.warn('No GC hook! Start your program as `node --expose-gc file.js`.'); } }
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
以上是Nodejs記憶體治理步驟詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

要連接 MySQL 資料庫,需要遵循以下步驟:安裝 mysql2 驅動程式。使用 mysql2.createConnection() 建立連接對象,其中包含主機位址、連接埠、使用者名稱、密碼和資料庫名稱。使用 connection.query() 執行查詢。最後使用 connection.end() 結束連線。

Node.js 中存在以下全域變數:全域物件:global核心模組:process、console、require執行階段環境變數:__dirname、__filename、__line、__column常數:undefined、null、NaN、Infinity、-Infinity

Node.js 安裝目錄中有兩個與 npm 相關的文件:npm 和 npm.cmd,區別如下:擴展名不同:npm 是可執行文件,npm.cmd 是命令視窗快捷方式。 Windows 使用者:npm.cmd 可以在命令提示字元中使用,npm 只能從命令列執行。相容性:npm.cmd 特定於 Windows 系統,npm 跨平台可用。使用建議:Windows 使用者使用 npm.cmd,其他作業系統使用 npm。

Node.js 和 Java 的主要差異在於設計和特性:事件驅動與執行緒驅動:Node.js 基於事件驅動,Java 基於執行緒驅動。單執行緒與多執行緒:Node.js 使用單執行緒事件循環,Java 使用多執行緒架構。執行時間環境:Node.js 在 V8 JavaScript 引擎上運行,而 Java 在 JVM 上運行。語法:Node.js 使用 JavaScript 語法,而 Java 使用 Java 語法。用途:Node.js 適用於 I/O 密集型任務,而 Java 適用於大型企業應用程式。

Node.js 和 Java 在 Web 開發中各有優劣,因此選擇取決於專案需求。 Node.js 擅長即時應用程式、快速開發和微服務架構,而 Java 則在企業級支援、效能和安全性方面佔優。

Node.js 專案的伺服器部署步驟:準備部署環境:取得伺服器存取權限、安裝 Node.js、設定 Git 儲存庫。建置應用程式:使用 npm run build 產生可部署程式碼和相依性。上傳程式碼到伺服器:透過 Git 或檔案傳輸協定。安裝依賴項:SSH 登入伺服器並使用 npm install 安裝應用程式相依性。啟動應用程式:使用 node index.js 等命令啟動應用程序,或使用 pm2 等進程管理器。設定反向代理(可選):使用 Nginx 或 Apache 等反向代理路由流量到應用程式
