我有一个(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的内存pipe理实现是如何实现的,因为mmap的参数有两种不同的变体。
PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE
这些参数分配地址空间,但是PROT_NONE意味着保留的地址空间不能被使用(除非另一个以后的调用使得它可访问)。
PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS
这些参数为特定的地址范围分配实际的内存(大概是先前用另一个参数组合分配的地址),并将其转换为读/写区域。
为什么这样做,我们可以从四个系统调用的序列中猜测:
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
这分配2MB的地址空间。 然后释放该地址空间的开始和结束,最后为分配的地址空间的中间部分分配1MB的内存。
有效地,这四个调用分配1MB的内存,其地址alignment1MB的倍数。 所以我们正在看一个明确希望alignment地址的模式。
后来的munmap调用只是释放之前分配的1MB块。 我特别注意到
munmap(0x336451500000, 1048576) = 0
这释放了上述四个系统调用中分配的1MB块。
所有这些可能不是你想知道的。 但不幸的是,这可以从strace输出中推导出来,所以你必须find其他方法来find你真正想知道的信息。
你可能会对这个function要求感兴趣的信号转储堆栈跟踪,这大概会是非常有用的,你现在。
另一种可能是将更多的日志代码添加到您的应用程序。