Problem
有时候你或许会搜集DB2 内存块(memory block)的详细信息以获取DB2所使用的私有内存集信息(private memory set)。比如,为了判断DB2私有内存集中是否发生了内存泄露,你可能需要运行命令“db2pd -memblock pid=” 以获取私有内存集(private set)中所有的DB2 内存块(memory block)信息。
然而,此时你必须清楚一点:运行上面的命令后DB2进程的私有堆内存使用量可能会显著提高。
而且,针对DB2其他进程,比如说 db2fmp, 运行命令“db2pd –memblock pid=”都可能会导致这些进程的堆内存使用量大幅度提高。
Symptom
举个例子,假设你的db2sysc 进程id 是23527694。
执行命令"db2pd -memblock pid=23527694"前,进程内存使用信息如下:
$ ps aux 23527694
USER PID %CPU %MEM SZ RSS TTY STAT STIME TIME COMMAND
db2inst1 23527694 0.0 0.0 40844 40616 - A 20:32:05 0:11 db2sysc
注意:SZ/RSS 表示该进程核心映像(core image)的大小和实际内存(驻留集/ resident set)大小,它们绝大部分都来至进程堆(process heap)。
但是,在执行命令"db2pd -memblock pid=23527694"后,进程内存使用量信息变成:
$ ps aux 23527694
USER PID %CPU %MEM SZ RSS TTY STAT STIME TIME COMMAND
db2inst1 23527694 0.0 0.2 439800 437520 - A 20:32:05 0:11 db2sysc
从上面你会发现私有堆内存使用量(对应SZ/RSS列)在执行db2pd命令后显著提高了。
Cause
db2pd 作为一个独立的进程不能attach到DB2私有内存集上,这不同于DB2共享内存集(比如DBMS/DB sets)。所以,db2pd可以从共享内存集(DB2 shared memory sets)中直接读取DB2内存结构去搜集内存块信息,但是对于私有内存集,db2pd却不能这样做。 因此,为了搜集db2sysc进程的所有DB2内存块信息,db2pd需要遍历整个进程堆以找出所有为DB2进程分配的内存块,这对DB2进程本身造成不小的影响。
db2pd 需要读取和检查所有的私有内存页 – 也包括那些曾经被释放的页。 而在Linux/AIX平台,当一个内存页面被读取时,会产生一个物理内存页或者分页空间页(physical memory page or paging space page)去做一个备份。因此,当db2pd遍历进程堆时,你会发现物理内存或者虚拟内存量大大增长,特别是当曾经有大量空闲内存页在私有堆的时候,这种情况更加显著,甚至于导致内存分页(memory paging)的发生。
Diagnosing The Problem
如果你发现DB2进程(比如db2sysc/db2fmp)的内存使用量在某时点显著提高了的时候,首先需要检查你是否在那个时点执行过“db2pd –memblock pid=”命令。
Resolving The Problem
为了避免这种情况发生,除非必须,你需要尽量避免执行这个命令。
[{"Product":{"code":"SSEPGG","label":"DB2 for Linux- UNIX and Windows"},"Business Unit":{"code":"BU053","label":"Cloud & Data Platform"},"Component":"Operating System \/ Hardware - Memory Management","Platform":[{"code":"PF002","label":"AIX"},{"code":"PF010","label":"HP-UX"},{"code":"PF016","label":"Linux"},{"code":"PF027","label":"Solaris"}],"Version":"9.8;9.7;9.5;10.1;10.5","Edition":"Advanced Enterprise Server;Enterprise Server;Express;Workgroup Server","Line of Business":{"code":"LOB10","label":"Data and AI"}}]