如何查询共享kdb进程中各变量与表的内存占用?
获取KDB进程中各变量/表的内存占用列表
刚好碰到过类似的共享KDB进程内存排查场景,给你几个直接能用的实用方案:
1. 基础版:遍历全局命名空间的所有变量
这个脚本可以快速列出全局空间下所有变量的内存占用,并按内存从大到小排序:
{[ns] // 获取目标命名空间下的所有变量名 vars: key ns; // 配对变量名和对应的内存大小(.Q.m返回字节数) memTable: flip (`varName;`memBytes)!(vars; .Q.m each value ns); // 按内存降序排列 `memBytes desc memTable }[`.]
- 把
[.]改成[yourNamespace]就能遍历指定命名空间的变量 .Q.m会返回对象实际占用的内存字节数,方便快速定位内存大户
2. 进阶版:过滤掉系统变量
全局命名空间里有很多KDB自带的系统变量(比如.Q、.z),如果只想看用户创建的变量,可以加个过滤逻辑:
{[ns] vars: key ns; // 排除以"."开头的系统变量 userVars: vars where not "."=first each string vars; memTable: flip (`varName;`memBytes)!(userVars; .Q.m each value ns[userVars]); `memBytes desc memTable }[`.]
3. 精细化:查看表的列级内存占用
如果某些大变量是表,你可能想知道具体哪列占内存最多,可以用这个扩展函数:
getObjMem: {[objName; obj] $[ // 判断是否为表类型(KDB中表的类型码是98h) 98h=type obj; // 表的话,返回列名和对应内存 flip (`varName;`colName;`memBytes)!(enlist objName; key obj; .Q.m each value obj); // 非表的话,返回变量名和内存 flip (`varName;`colName;`memBytes)!(enlist objName; enlist `_; enlist .Q.m obj) ] }; // 调用方式:遍历全局用户变量并生成详细内存表 {[ns] vars: key ns where not "."=first each string key ns; raze getObjMem[;] each (vars; value ns[vars]) }[`.]
这个脚本会把表的每一列都拆出来显示,方便精准定位表内的内存消耗点。
注意事项
.Q.m计算的是单个对象的内存,如果多个变量引用同一个对象(比如a:table; b:a),每个变量的.Q.m结果会相同,但实际内存只占用一份,清理时要注意避免误删被共享的对象- 如果你的KDB版本比较旧,
.Q.m可能需要替换成底层内存查询函数-3!,用法是-3!obj,返回的也是字节数
内容的提问来源于stack exchange,提问作者kenwjj
相关产品推荐
相关产品推荐

