我最近将一些java应用程序转换为使用linux手动configuration的hugepages运行,如下所述。 我指出“手动configuration”,因为它们不是透明的巨大页面 ,这给我们一些性能问题 。
所以现在,我已经有10个tomcat在系统上运行了,而且我有兴趣知道每个用户有多less内存。
我可以像Linux Huge Pages Usage Accounting中所描述的那样从/proc/meminfo获得摘要信息。
但我找不到任何工具告诉我有关每个进程的巨大页面使用情况。
我在/proc/pid/numa_stat ,发现了一些有趣的信息,使我感到这种毛病:
function pshugepage () { HUGEPAGECOUNT=0 for num in `grep 'anon_hugepage.*dirty=' /proc/$@/numa_maps | awk '{print $6}' | sed 's/dirty=//'` ; do HUGEPAGECOUNT=$((HUGEPAGECOUNT+num)) done echo process $@ using $HUGEPAGECOUNT huge pages }
或者这个,在perl中:
sub counthugepages { my $pid=$_[0]; open (NUMAMAPS, "/proc/$pid/numa_maps") || die "can't open numa_maps"; my $HUGEPAGECOUNT=0; while (my $line=<NUMAMAPS>) { next unless ($line =~ m{ huge }) ; next unless ($line =~ m{dirty=}); chomp $line; $line =~ s{.*dirty=}{}; $line =~ s{\s.*$}{}; $HUGEPAGECOUNT+=$line; } close NUMAMAPS; # we want megabytes out, but we counted 2-megabyte hugepages return ($HUGEPAGECOUNT*2); }
它给我的数字是合理的,但我很不自信这种方法是正确的。
环境是一个四CPU戴尔,64GB ram,RHEL6.3,oracle jdk 1.7.x(目前为20130728)
更新: Red Hat现在推荐这种方法在RHEL5 / 6上进行进程巨大页面记帐:
grep -B 11 'KernelPageSize: 2048 kB' /proc/[PID]/smaps \ | grep "^Size:" \ | awk 'BEGIN{sum=0}{sum+=$2}END{print sum/1024}'
我在procps-ng开发者的邮件列表上问了这个问题。 有人告诉我:
在几个月前procps-ng / pmap工具中已经引入了巨大的页面支持(开关-XX,-C,-c,-N,-n应该允许你configuration和显示正在运行的内核所支持的任何条目)。
我在fedora 19上用procps-3.3.8试了一下。我不认为它给了我任何我没有从我提出的问题中得到的信息,但至less它有权威的光环。
FWIW我结束了以下几点:
.pmaprc文件包含:
[Fields Display] Size Rss Pss Referenced AnonHugePages KernelPageSize Mapping [Mapping] ShowPath
然后我使用下面的命令来获取巨大的页面信息:
pmap -c [process id here] | egrep 'Add|2048'
在grep中,“Add”用于标题行。 “2048”将抓取任何内核页面大小为2048的页面,即大页面。 它也将抓住不相关的东西。
以下是一些示例输出:
Address Size Rss Pss Referenced AnonHugePages KernelPageSize Mapping ed800000 22528 0 0 0 0 2048 /anon_hugepage (deleted) f7e00000 88064 0 0 0 0 2048 /anon_hugepage (deleted) fd400000 45056 0 0 0 0 2048 /anon_hugepage (deleted) 7f3753dff000 2052 2048 2048 2048 2048 4 [stack:1674] 7f3759000000 4096 0 0 0 0 2048 /anon_hugepage (deleted) 7f3762d68000 2048 0 0 0 0 4 /usr/lib64/libc-2.17.so 7f376339b000 2048 0 0 0 0 4 /usr/lib64/libpthread-2.17.so
我们只关心kernelPageSize 2048的行。
我想这是告诉我,我已经在庞大的页面中分配了159744千字节(22528 + 88064 + 45056 + 4096)的RAM。 我告诉java正好使用128M的堆,而且还有一些其他的内存池,所以这是一个合理的数字。 Rss&Referenced 0不太合理,但是testingjava程序非常简单,所以也是合理的。
它不同意我从上面的perl代码中得到的数字,因为perl只search“脏”的页面 – 实际上已经被使用的页面。 和/或因为Perl是错误的,我不知道。
我也在RHEL6机器上尝试了procps 3.3.9,使用了大量的巨大页面内存。 Rss&Referenced列全部为0.这可能是内核的错,而不是procps,我不知道。
改进的Perl脚本
#!/usr/bin/perl # sub counthugepages { my $pid=$_[0]; open (NUMAMAPS, "/proc/$pid/numa_maps") || die "can't open numa_maps"; my $HUGEPAGECOUNT=0; while (<NUMAMAPS>) { if (/huge.*dirty=(\d+)/) { $HUGEPAGECOUNT+=$1; } } close NUMAMAPS; return ($HUGEPAGECOUNT); } printf "%d huge pages\n",counthugepages($ARGV[0]);