我有一个 (node.js) 应用程序,它偶尔会导致 100% 的 CPU 使用率。当它处于这种状态时,我已经附加到该过程strace
- 但如果 strace 输出,我不知道该怎么做。结果在这两种模式之间重复(缩短):
mmap(0x30c3ac700000, 1048576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x30c3ac700000
mmap(0x3364514ba000, 2097152, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x3364514ba000
munmap(0x3364514ba000, 286720) = 0
munmap(0x336451600000, 761856) = 0
mmap(0x336451500000, 1048576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x336451500000
mmap(0x2b9c33880000, 2097152, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x2b9c33880000
munmap(0x2b9c33880000, 524288) = 0
munmap(0x2b9c33a00000, 524288) = 0
...
和...
munmap(0x2b9c33900000, 1048576) = 0
munmap(0x336451500000, 1048576) = 0
munmap(0x30c3ac700000, 1048576) = 0
munmap(0x247e37500000, 1048576) = 0
munmap(0x20d76c800000, 1048576) = 0
munmap(0x1cae0d600000, 1048576) = 0
munmap(0x163545100000, 1048576) = 0
munmap(0x32dcfe700000, 1048576) = 0
munmap(0x1a1feff00000, 1048576) = 0
munmap(0x3fb72f00000, 1048576) = 0
munmap(0x366536900000, 1048576) = 0
...
任何人都可以阐明这里可能发生的事情吗?谢谢!
从这个输出可以推断出应用程序正在分配和释放内存。所以肯定有一些数据结构在增长和缩小。
不幸的是,这并没有说明应用程序更高层发生的事情。
我们还可以推断出内存管理实现
node.js
是如何实现的,因为mmap
.这些参数分配地址空间,但
PROT_NONE
意味着不能使用保留的地址空间(除非稍后的另一个调用使其可访问)。这些参数为特定范围的地址分配实际内存(可能是先前与其他参数组合分配的)并将其转换为读/写区域。
为什么会这样,我们可以通过查看这四个系统调用的序列来猜测:
这将分配 2MB 的地址空间。然后释放该地址空间的开始和结束,最后为分配的地址空间的中间部分分配 1MB 内存。
实际上,这四个调用分配了 1MB 的内存,地址对齐为 1MB 的倍数。因此,我们正在研究一种明确需要对齐地址的模式。
后面的
munmap
调用只是释放之前分配的 1MB 块。我特别注意到这释放了在上述四个系统调用中分配的 1MB 块。
这一切可能不是你想知道的。但不幸的是,这是可以从
strace
输出中推断出来的,所以你必须找到其他方法来找到你真正想知道的信息。您可能对转储堆栈跟踪的信号的此功能请求感兴趣,这可能对您现在非常有用。
另一种可能性是向您的应用程序添加更多日志记录代码。