【发布时间】:2017-03-06 09:53:39
【问题描述】:
我发现了一个触发大量内核时间的 java 进程,以查看正在使用哪些系统调用,并且惊讶地发现 gettimeofday() 和 clock_gettime() 占主导地位(我怀疑这是由于日志记录),这考虑到man vdso 状态,这很奇怪:
使用 strace(1) 跟踪系统调用时,vDSO 导出的符号(系统调用)不会出现在跟踪输出中。
这些系统调用是怎么发生的?有没有办法避免它们?
机器在 EC2 上运行 Ubuntu 16.04.1。
为了让事情变得更简单,我用 C (testgtod.c) 创建了一个最小的测试程序:
#include <stdlib.h>
#include <sys/time.h>
void main(void)
{
struct timeval tv;
for(int i = 0; i < 1000; i++) {
/* glibc wrapped, shouldn't actually syscall */
gettimeofday(&tv, NULL);
}
}
然后我在 strace 下编译运行程序:gcc testgtod.c -o testgtod && sudo strace ./testgtod
出乎我的意料,输出包括对 gettimeofday() 的一千次调用。
我测试的东西以确保我没有看到东西:
使用
file确保二进制文件是64位精灵-
ldd ./testgtod确保 vDSO 处于活动状态:linux-vdso.so.1 => (0x00007ffcee25d000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f6f6e161000) /lib64/ld-linux-x86-64.so.2 (0x0000559ed71f3000)
getauxval(AT_SYSINFO_EHDR) != NULL将
gettimeofday(&tv, NULL)调用替换为syscall(SYS_gettimeofday, &tv, NULL),调用数量增加到 1000 万,运行在time之下 - 两种情况下的运行时行为相同:./testgtod 0.16s user 0.83s system 99% cpu 0.998 total。
【问题讨论】:
标签: amazon-ec2 linux-kernel vdso