process 属性与运行时上下文

本章解决的问题

工作原理

process 是 Node.js 提供的全局对象,代表当前操作系统进程。它暴露启动上下文、资源统计、标准流和生命周期事件。虽然 TypeScript 中可直接使用,为了明确来源也可以写:

import process from "node:process";

本项目编译为 CommonJS;import 只是 TypeScript 源码写法,实际运行模块格式仍由 tsconfig.jsonmodule 决定。

高频 API

const report = {
  pid: process.pid,
  ppid: process.ppid,
  platform: process.platform,
  arch: process.arch,
  nodeVersion: process.version,
  componentVersions: process.versions,
  cwd: process.cwd(),
  uptimeSeconds: process.uptime(),
  memory: process.memoryUsage(),
  cpu: process.cpuUsage(),
  resources: process.resourceUsage(),
};

console.log(report);

版本和目录

内存

process.memoryUsage() 常见字段均以字节计:

CPU

process.cpuUsage() 返回用户态和内核态消耗的微秒数,不是 CPU 百分比。传入上次结果可得到区间差值:

const startCpu: NodeJS.CpuUsage = process.cpuUsage();
const startTime: number = Date.now();

setTimeout(() => {
  const elapsedMs: number = Date.now() - startTime;
  const delta: NodeJS.CpuUsage = process.cpuUsage(startCpu);

  console.log({ elapsedMs, cpuMicroseconds: delta });
}, 1_000);

CPU 百分比还涉及时间区间和多核定义,不应直接把 user 当作百分比展示。

具体代码:安全诊断报告

interface RuntimeReport {
  pid: number;
  ppid: number;
  node: string;
  executable: string;
  platform: NodeJS.Platform;
  arch: string;
  cwd: string;
  uptimeSeconds: number;
  rssMiB: number;
  heapUsedMiB: number;
}

const bytesToMiB = (bytes: number): number =>
  Math.round((bytes / 1024 / 1024) * 100) / 100;

const memory: NodeJS.MemoryUsage = process.memoryUsage();

const report: RuntimeReport = {
  pid: process.pid,
  ppid: process.ppid,
  node: process.version,
  executable: process.execPath,
  platform: process.platform,
  arch: process.arch,
  cwd: process.cwd(),
  uptimeSeconds: Math.round(process.uptime()),
  rssMiB: bytesToMiB(memory.rss),
  heapUsedMiB: bytesToMiB(memory.heapUsed),
};

process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);

这个报告故意不输出完整 process.env、命令行秘密或业务数据。

正常时间线

启动进程 → 读取静态上下文 → 采集资源快照 → 输出结构化报告 → 自然退出

异常时间线

内存持续增长 → 周期性快照显示 rss/heapUsed 上升
→ 达到进程或系统限制 → GC 频繁或分配失败 → 服务变慢/崩溃

单次快照不能证明内存泄漏。应在相同负载阶段比较趋势,并区分 JS 堆、Buffer 和本地内存。

Windows 与 Linux

常见错误

  1. cwd 当成源码目录:它是“从哪里启动”,不是“文件在哪里”。
  2. 只看 heapUsed 判断总内存:大量 Buffer 可能体现在 externalarrayBuffersrss
  3. 每个请求都打印完整资源报告:增加 I/O 和日志噪音。
  4. process.env 整体写入日志:可能泄露密码、令牌和连接串。
  5. 看到 RSS 暂未下降就认定泄漏:运行时可能保留已申请内存供后续复用。

最佳实践

练习题

  1. 扩展报告,添加 externalMiBarrayBuffersMiB
  2. 分配一个 50 MiB 的 Buffer,比较前后的内存字段。
  3. 分别从项目目录和上级目录运行同一脚本,观察 cwd

验收点