为什么 Node.js 启动后虚拟内存很大

问题来源

问题来源于cnode社区:node启动占用内存的问题

自己本地跑了一下,乖乖不得了,启动一个 node,什么都不做。结果是这样子的:果然900+M

undefined

我的电脑信息:

$cat /proc/version
Linux version 4.13.0-38-generic (buildd@lgw01-amd64-027) (gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.9)) #43~16.04.1-Ubuntu SMP Wed Mar 14 17:48:43 UTC 2018
$cat /proc/cpuinfo | grep processor
processor    : 0
processor    : 1
processor    : 2
processor    : 3

我们知道,进程真正从OS拿到的内存是RSS,一般意义上讲,进程占了多少内存就是这个RSS。因此,cnode 社区的这个标题有点欠妥。

那么我就求证一下 node 到底在哪里申请了这么多虚拟内存。

求证过程

pmap 查看虚拟内存使用情况

下面命令输出中把一些100KB以下的信息省略,有兴趣的同学可以自己查看。

$ pmap -d 28708
28708:   ./node
Address           Kbytes Mode  Offset           Device    Mapping
0000000000400000   28540 r-x-- 0000000000000000 008:00005 node
00000000021df000       4 r---- 0000000001bdf000 008:00005 node
00000000021e0000     104 rw--- 0000000001be0000 008:00005 node
00000000021fa000    2168 rw--- 0000000000000000 000:00000   [ anon ]
0000000003bd6000    1352 rw--- 0000000000000000 000:00000   [ anon ]
0000031078d80000     512 rw--- 0000000000000000 000:00000   [ anon ]
000003cf96a00000     512 rw--- 0000000000000000 000:00000   [ anon ]
00000439e7900000     512 rw--- 0000000000000000 000:00000   [ anon ]
0000083024e00000     512 ----- 0000000000000000 000:00000   [ anon ]
000008c587300000     512 rw--- 0000000000000000 000:00000   [ anon ]
00000b1f3fb00000     512 ----- 0000000000000000 000:00000   [ anon ]
00000f247cf80000     512 rw--- 0000000000000000 000:00000   [ anon ]
0000169de244f000     196 ----- 0000000000000000 000:00000   [ anon ]
0000169de2485000     492 ----- 0000000000000000 000:00000   [ anon ]
0000169de2505000     492 ----- 0000000000000000 000:00000   [ anon ]
0000169de2585000     492 ----- 0000000000000000 000:00000   [ anon ]
0000169de2604000     492 rwx-- 0000000000000000 000:00000   [ anon ]
0000169de2684000     492 rwx-- 0000000000000000 000:00000   [ anon ]
0000169de2704000     492 rwx-- 0000000000000000 000:00000   [ anon ]
0000169de27ff000  520512 ----- 0000000000000000 000:00000   [ anon ]
000017db76f80000     316 rw--- 0000000000000000 000:00000   [ anon ]
0000219337b00000     512 rw--- 0000000000000000 000:00000   [ anon ]
000025cdf0280000     512 rw--- 0000000000000000 000:00000   [ anon ]
000025e610580000     512 ----- 0000000000000000 000:00000   [ anon ]
000026bff1500000     512 rw--- 0000000000000000 000:00000   [ anon ]
000028eaed980000     512 ----- 0000000000000000 000:00000   [ anon ]
0000309c9b900000     512 rw--- 0000000000000000 000:00000   [ anon ]
000031a7c5980000     512 ----- 0000000000000000 000:00000   [ anon ]
0000389d07380000     512 rw--- 0000000000000000 000:00000   [ anon ]
00003a0dee480000     512 rw--- 0000000000000000 000:00000   [ anon ]
00007f1630000000     132 rw--- 0000000000000000 000:00000   [ anon ]
00007f1630021000   65404 ----- 0000000000000000 000:00000   [ anon ]
00007f1634000000     132 rw--- 0000000000000000 000:00000   [ anon ]
00007f1634021000   65404 ----- 0000000000000000 000:00000   [ anon ]
00007f1638ffb000    8192 rw--- 0000000000000000 000:00000   [ anon ]
00007f16397fc000    8192 rw--- 0000000000000000 000:00000   [ anon ]
00007f1639ffd000    8192 rw--- 0000000000000000 000:00000   [ anon ]
00007f163a7fe000    8192 rw--- 0000000000000000 000:00000   [ anon ]
00007f163afff000    8192 rw--- 0000000000000000 000:00000   [ anon ]
00007f163b800000    8192 rw--- 0000000000000000 000:00000   [ anon ]
00007f163c000000     132 rw--- 0000000000000000 000:00000   [ anon ]
00007f163c021000   65404 ----- 0000000000000000 000:00000   [ anon ]
00007f1640000000     132 rw--- 0000000000000000 000:00000   [ anon ]
00007f1640021000   65404 ----- 0000000000000000 000:00000   [ anon ]
00007f1644000000     132 rw--- 0000000000000000 000:00000   [ anon ]
00007f1644021000   65404 ----- 0000000000000000 000:00000   [ anon ]
00007f1648713000    8192 rw--- 0000000000000000 000:00000   [ anon ]
00007f1648f14000    8192 rw--- 0000000000000000 000:00000   [ anon ]
00007f1649715000    8192 rw--- 0000000000000000 000:00000   [ anon ]
00007f1649f16000    8192 rw--- 0000000000000000 000:00000   [ anon ]
00007f164a716000    1792 r-x-- 0000000000000000 008:00005 libc-2.23.so
00007f164a8d6000    2048 ----- 00000000001c0000 008:00005 libc-2.23.so
00007f164aaf8000    2044 ----- 0000000000018000 008:00005 libpthread-2.23.so
00007f164ad13000    2044 ----- 0000000000016000 008:00005 libgcc_s.so.1
00007f164af13000    1056 r-x-- 0000000000000000 008:00005 libm-2.23.so
00007f164b01b000    2044 ----- 0000000000108000 008:00005 libm-2.23.so
00007f164b21c000    1480 r-x-- 0000000000000000 008:00005 libstdc++.so.6.0.21
00007f164b38e000    2048 ----- 0000000000172000 008:00005 libstdc++.so.6.0.21
00007f164b5a5000    2044 ----- 0000000000007000 008:00005 librt-2.23.so
00007f164b7a9000    2044 ----- 0000000000003000 008:00005 libdl-2.23.so
00007f164b9aa000     152 r-x-- 0000000000000000 008:00005 ld-2.23.so
00007ffc8810d000     136 rw--- 0000000000000000 000:00000   [ stack ]
mapped: 994068K    writeable/private: 94540K    shared: 0K

最后一行的信息:

我有几张阿里云幸运券分享给你,用券购买或者升级阿里云相应产品会有特惠惊喜哦!把想要买的产品的幸运券都领走吧!快下手,马上就要抢光了。

  • mapped 表示该进程映射的虚拟地址空间大小,也就是该进程预先分配的虚拟内存大小,即ps出的vsz
  • writeable/private 表示进程所占用的私有地址空间大小,也就是该进程实际使用的内存大小
  • shared 表示进程和其他进程共享的内存大小

命令输出信息具体含义,跟 liunx 下内存管理相关,那个话题实在太大,这里只关注虚拟内存哪里来的这个问题。

上面的输出结果中,大头是下面这几列。一共 500+M + 64M * 5,大约 800+M

0000169de27ff000  520512 ----- 0000000000000000 000:00000   [ anon ]
00007f1630021000   65404 ----- 0000000000000000 000:00000   [ anon ]
00007f1634021000   65404 ----- 0000000000000000 000:00000   [ anon ]
00007f163c021000   65404 ----- 0000000000000000 000:00000   [ anon ]
00007f1640021000   65404 ----- 0000000000000000 000:00000   [ anon ]
00007f1644021000   65404 ----- 0000000000000000 000:00000   [ anon ]

具体占用情况

作为一个程序员,基本一看就知道分两类,512M 和 64M

下面这段话来自Java程序在Linux上运行虚拟内存耗用很大

我们知道Linux下glibc的内存管理机制用了一个很奇妙的东西,叫arena。在glibc分配内存的时候,大内存从从中央分配区分配,小内存则在线程创建时,从缓存区分配。为了解决分配内存的性能的问题,就引入了这个叫做arena的memory pool。而恰好,在64bit系统下面,它的缺省配置为64M。

Red Hat Enterprise Linux 6 features version 2.11 of glibc, providing many features and enhancements, including… An enhanced dynamic memory allocation (malloc) behaviour enabling higher scalability across many sockets and cores.This is achieved by assigning threads their own memory pools and by avoiding locking in some situations. The amount of additional memory used for the memory pools (if any) can be controlled using the environment variables MALLOC_ARENA_TEST and MALLOC_ARENA_MAX. MALLOC_ARENA_TEST specifies that a test for the number of cores is performed once the number of memory pools reaches this value. MALLOC_ARENA_MAX sets the maximum number of memory pools used, regardless of the number of cores.

验证一下:

原文链接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值