中文字幕第五页-中文字幕第页-中文字幕韩国-中文字幕最新-国产尤物二区三区在线观看-国产尤物福利视频一区二区

Node中堆內存分配的示例分析

這篇文章將為大家詳細講解有關Node中堆內存分配的示例分析,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

讓客戶滿意是我們工作的目標,不斷超越客戶的期望值來自于我們對這個行業(yè)的熱愛。我們立志把好的技術通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領域值得信任、有價值的長期合作伙伴,公司提供的服務項目有:主機域名、虛擬空間、營銷軟件、網站建設、洪雅網站維護、網站推廣。

V8 垃圾回收簡介

首先,簡單介紹一下V8垃圾回收器。內存的存儲分配方式是堆(heap),堆被分為幾個世代(generational)區(qū)域。 對象在它的生命周期中隨著年齡的變化,它所屬的世代也有所不同。

世代中分為年輕一代和老一代,而年輕的一代還分為了新生代和中間代。隨著對象在垃圾回收中幸存下來,它們也會加入老一代。

Node中堆內存分配的示例分析

世代假說的基本原則是大多數(shù)對象都是年輕的。V8 垃圾回收器基于這一點,只提升在垃圾回收中幸存下來的對象。隨著對象被復制到相鄰區(qū)域,它們最終會進入老一代。

在Nodejs中內存消耗主要分為三個方面:

  • 代碼-代碼執(zhí)行時所在的位置

  • 調用棧-用于存放具有原始類型(數(shù)字,字符串或布爾值)的函數(shù)和局部變量

  • 堆內存

堆內存是我們今天的主要關注點。 現(xiàn)在您對垃圾回收器有了更多的了解,是時候在堆上分配一些內存了!

function allocateMemory(size) {
  // Simulate allocation of bytes
  const numbers = size / 8;
  const arr = [];
  arr.length = numbers;
  for (let i = 0; i < numbers; i++) {
    arr[i] = i;
  }
  return arr;
}

在調用棧中,局部變量隨著函數(shù)調用結束而銷毀。基礎類型 number永遠不會進入堆內存,而是在調用棧中分配。但是對象arr將進入堆中并且可能在垃圾回收中幸存下來。

堆內存有限制嗎?

現(xiàn)在進行勇敢測試——將 Node 進程推到極限看看在哪個地方會耗盡堆內存:

const memoryLeakAllocations = [];

const field = "heapUsed";
const allocationStep = 10000 * 1024; // 10MB

const TIME_INTERVAL_IN_MSEC = 40;

setInterval(() => {
  const allocation = allocateMemory(allocationStep);

  memoryLeakAllocations.push(allocation);

  const mu = process.memoryUsage();
  // # bytes / KB / MB / GB
  const gbNow = mu[field] / 1024 / 1024 / 1024;
  const gbRounded = Math.round(gbNow * 100) / 100;

  console.log(`Heap allocated ${gbRounded} GB`);
}, TIME_INTERVAL_IN_MSEC);

在上面的代碼中,我們以 40 毫秒的間隔分配了大約 10 mb,為垃圾回收提供了足夠的時間來將幸存的對象提升到老年代。process.memoryUsage 是一個用于回收有關堆利用率的粗略指標的工具。隨著堆分配的增長,heapUsed 字段會記錄堆的大小。這個字段記錄 RAM 中的字節(jié)數(shù),可以轉換為mb。

你的結果可能會有所不同。在32GB 內存的 Windows 10 筆記本電腦會得到以下結果:

Heap allocated 4 GB
Heap allocated 4.01 GB

<--- Last few GCs --->

[18820:000001A45B4680A0] 26146 ms: Mark-sweep (reduce) 4103.7 (4107.3) -> 4103.7 (4108.3) MB, 1196.5 / 0.0 ms (average mu = 0.112, current mu = 0.000) last resort GC in old space requested

<--- JS stacktrace --->

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory

在這里,垃圾回收器將嘗試壓縮內存作為最后的手段,最后放棄并拋出“堆內存不足”異常。這個過程達到了 4.1GB 的限制,需要 26.6 秒才能意識到要把服務給掛掉了。

導致以上結果的原因有些還未知。V8 垃圾回收器最初運行在具有嚴格內存限制的 32 位瀏覽器進程中。這些結果表明內存限制可能已經從遺留代碼中繼承下來。

在撰寫本文時,以上代碼在最新的 LTS Node 版本下運行,并且使用的是 64 位可執(zhí)行文件。從理論上講,一個 64 位進程應該能夠分配超過 4GB 的空間,并且可以輕松地增長到 16 TB 的地址空間。

擴大內存分配限制

node index.js --max-old-space-size=8000

這將最大限制設置為 8GB。這樣做時要小心。我的筆記本電腦有 32GB的空間。我建議將其設置為 RAM 中實際可用的空間。一旦物理內存耗盡,進程就會開始通過虛擬內存占用磁盤空間。如果您將限制設置得太高,你就get了換電腦的新理由,這里咱們盡量避免電腦冒煙了哈~

我們再用8GB的限制再跑一次代碼:

Heap allocated 7.8 GB
Heap allocated 7.81 GB

<--- Last few GCs --->

[16976:000001ACB8FEB330] 45701 ms: Mark-sweep (reduce) 8000.2 (8005.3) -> 8000.2 (8006.3) MB, 1468.4 / 0.0 ms (average mu = 0.211, current mu = 0.000) last resort GC in old space requested

<--- JS stacktrace --->

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory

這一次堆的大小幾乎達到 8GB,但沒完全達到。我懷疑是Node 進程中有一些開銷用于分配這么多內存。這次進程結束需要 45.7 秒。

在生產環(huán)境中,內存全部用完可能不會少于一分鐘。這就是監(jiān)控和洞察內存消耗有幫助的原因之一。內存消耗會隨著時間的推移緩慢增長,并且可能需要幾天時間才能知道存在問題。如果進程不斷崩潰并且日志中出現(xiàn)“堆內存不足”異常,則代碼中可能存在內存泄漏。

進程也可能會占用更多內存,因為它正在處理更多數(shù)據(jù)。如果資源消耗繼續(xù)增長,可能是時候將這個單體分解為微服務了。這將減少單個進程的內存壓力,并允許節(jié)點水平擴展。

如何跟蹤 Node.js 內存泄漏

process.memoryUsage 的 heapUsed  字段還是有點用的,調試內存泄漏的一個方法是將內存指標放在另一個工具中以進行進一步處理。由于此實現(xiàn)并不復雜,因此主要解析下如何親自實現(xiàn)。

const path = require("path");
const fs = require("fs");
const os = require("os");

const start = Date.now();
const LOG_FILE = path.join(__dirname, "memory-usage.csv");

fs.writeFile(LOG_FILE, "Time Alive (secs),Memory GB" + os.EOL, () => {}); // 請求-確認

為了避免將堆分配指標放在內存中,我們選擇將結果寫入 CSV 文件以方便數(shù)據(jù)消耗。這里使用了 writeFile 帶有回調的異步函數(shù)。回調為空以寫入文件并繼續(xù),無需任何進一步處理。 要獲取漸進式內存指標,請將其添加到 console.log:

const elapsedTimeInSecs = (Date.now() - start) / 1000;
const timeRounded = Math.round(elapsedTimeInSecs * 100) / 100;

s.appendFile(LOG_FILE, timeRounded + "," + gbRounded + os.EOL, () => {}); // 請求-確認

上面這段代碼可以用來調試內存泄漏的情況下,堆內存隨著時間變化而增長。你可以使用一些分析工具來解析原生csv數(shù)據(jù)以實現(xiàn)一個比較漂亮的可視化。

如果你只是趕著看看數(shù)據(jù)的情況,直接用excel也可以,如下圖:

Node中堆內存分配的示例分析

在限制為4.1GB的情況下,你可以看到內存的使用率在短時間內呈線性增長。內存的消耗在持續(xù)的增長并沒有變得平緩,這個說明了某個地方存在內存泄漏。在我們調試這類問題的時候,我們要尋找在分配在老世代結束時的那部分代碼。

對象如果再在垃圾回收時幸存下來,就可能會一直存在,直到進程終止。

使用這段內存泄漏檢測代碼更具復用性的一種方法是將其包裝在自己的時間間隔內(因為它不必存在于主循環(huán)中)。

setInterval(() => {
  const mu = process.memoryUsage();
  // # bytes / KB / MB / GB
  const gbNow = mu[field] / 1024 / 1024 / 1024;
  const gbRounded = Math.round(gbNow * 100) / 100;

  const elapsedTimeInSecs = (Date.now() - start) / 1000;
  const timeRounded = Math.round(elapsedTimeInSecs * 100) / 100;

  fs.appendFile(LOG_FILE, timeRounded + "," + gbRounded + os.EOL, () => {}); // fire-and-forget
}, TIME_INTERVAL_IN_MSEC);

要注意上面這些方法并不能直接在生產環(huán)境中使用,僅僅只是告訴你如何在本地環(huán)境調試內存泄漏。在實際實現(xiàn)時還包括了自動顯示、警報和輪換日志,這樣服務器才不會耗盡磁盤空間。

跟蹤生產環(huán)境中的 Node.js 內存泄漏

盡管上面的代碼在生產環(huán)境中不可行,但我們已經看到了如何去調試內存泄漏。因此,作為替代方案,可以將 Node 進程包裹在 PM2 之類 的 守護進程 中。

當內存消耗達到限制時設置重啟策略:

pm2 start index.js --max-memory-restart 8G

單位可以是 K(千字節(jié))、M(兆字節(jié))和 G(千兆字節(jié))。進程重啟大約需要 30 秒,因此通過負載均衡器配置多個節(jié)點以避免中斷。

另一個漂亮的工具是跨平臺的原生模塊node-memwatch,它在檢測到運行代碼中的內存泄漏時觸發(fā)一個事件。

const memwatch = require("memwatch");

memwatch.on("leak", function (info) {  // event emitted  console.log(info.reason);
});復制代碼

事件通過leak觸發(fā),并且它的回調對象中有一個reason會隨著連續(xù)垃圾回收的堆增長而增長。

使用 AppSignal 的 Magic Dashboard 診斷內存限制

AppSignal 有一個神奇的儀表板,用于監(jiān)控堆增長的垃圾收集統(tǒng)計信息。

Node中堆內存分配的示例分析

上圖顯示請求在 14:25 左右停止了 7 分鐘,允許垃圾回收以減少內存壓力。當對象在舊的空間中停留太久并導致內存泄漏時,儀表板也會暴露出來。

關于“Node中堆內存分配的示例分析”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

分享標題:Node中堆內存分配的示例分析
本文網址:http://www.2m8n56k.cn/article26/giosjg.html

成都網站建設公司_創(chuàng)新互聯(lián),為您提供外貿網站建設App設計服務器托管域名注冊標簽優(yōu)化虛擬主機

廣告

聲明:本網站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:[email protected]。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

外貿網站制作
主站蜘蛛池模板: 成 人 a v黄 色 | 国产免费福利体检区久久 | 亚洲女精品一区二区三区 | 亚洲国产日韩综合久久精品 | 国产成人影院一区二区 | 悟空影视大全免费高清 | 国内高清久久久久久久久 | 久久久国产99久久国产一 | 精品91自产拍在线 | 午夜大片免费男女爽爽影院久久 | 久久久久久久99精品免费 | 美女wc | 在线看免费观看韩国特黄一级 | 亚洲国产最新在线一区二区 | 亚洲社区在线 | 97视频免费播放观看在线视频 | 模特精品一区二区三区 | 美女日韩在线观看视频 | 国产在线精品一区二区夜色 | 亚洲人成影院午夜网站 | 久草在线视频在线观看 | 全国最大色成免费网站 | 精品在线看 | 国产成人福利美女观看视频 | 手机在线毛片免费播放 | 国产精品久久久久久一区二区 | 久草网视频在线 | 青青久草| 成人免费大片a毛片 | 久久手机免费视频 | 一级女性生活片 | 特黄特色三级在线播放 | 99久久伊人一区二区yy5o99 | 欧美日韩一区二区三区视视频 | 王朝影院一区二区三区入口 | 韩国美女爽快一毛片免费 | 日韩欧美一区二区三区久久 | 国产激情视频在线播放 | www亚洲精品| 日韩精品一二三区 | 全部免费毛片在线 |