我们正在使用 SQLCLR 存储过程来激活服务代理,并且我想监视 CLR 代码使用的内存。查看sys.dm_os_memory_clerks
,我看到只有 NUMA 节点 1 具有与该MEMORYCLERK_SQLCLR
类型关联的任何页面。该服务器有两个 8 核 CPU,运行 SQL 2014 CU6。
这是预期的吗?或者我应该像我一样看到两个节点上使用的内存MEMORYCLERK_SQLBUFFERPOOL
吗?
询问:
SELECT DOMC.memory_node_id
, DOMC.pages_kb
, DOMC.virtual_memory_reserved_kb
, DOMC.virtual_memory_committed_kb
FROM sys.dm_os_memory_clerks DOMC where type = 'MEMORYCLERK_SQLCLR'
结果:
memory_node_id pages_kb virtual_memory_reserved_kb virtual_memory_committed_kb
-------------- -------------------- -------------------------- ---------------------------
0 88232 12607744 1408652
1 0 0 0
64 0 0 0
不幸的是,没有大量关于 SQLCLR 内存使用细节的信息。但是,我确实发现以下两个资源作为起点很有帮助:
从这些并查看各种 DMV 和 MSDN 页面,解释(嗯,解释不多,但从技术上讲,这不仅仅是什么)这些 DMV 如何工作,我整理了下面显示的查询。从在几个不同的系统上运行这些,似乎 SQLCLR 内存分配集中在一个特定
memory_node_id
的,但在其他节点上仍然有一些分配,至少在 Proc Cache 方面。所以就目前而言,除非有人有相反的证据或信息,否则你所经历的是“预期的”。此查询报告基本信息:
您会注意到,如果不指定一个特定
[type]
的,还有一些可能会占用一些内存。我见过的总共4种类型是:如果您想知道为什么我要过滤掉
[memory_node_id]
64 个,请运行以下命令:并且您将看到 64 的 node_id 是 DAC(专用管理员连接)。
以下将为您提供两个重要字段的总数。请注意,SQL Server 2012 中的字段已更改,因此您需要选择适合其所使用的 SQL Server 版本的字段:
下一个查询显示“memory_clerks”和“memory_objects”之间的关系:
以下查询是第一个查询的更集中的版本(更像是问题中的查询),但 SQL Server 2012 中的字段发生了变化,因此您需要选择适合其正在使用的 SQL Server 版本的字段用于:
更新:
我通过创建 2 个数据库并使用静态变量将 80 MB 加载到每个数据库中,在双处理器系统上做了一些额外的测试。我创建了两个数据库而不是一个,以查看 AppDomain 是否必须保留在一个内存节点上,是否能够至少将另一个 AppDomain 放置在另一个内存节点上以分散内容。结果:
[virtual_memory_committed_kb]
领域sys.dm_os_memory_clerks
。而“任务管理器”中的“Commit Size”一栏也反映了这一增长。