Service Brokerのアクティブ化にSQLCLRストアドプロシージャを使用しています。CLRコードで使用されるメモリを監視したいと思います。 sys.dm_os_memory_clerks
を見ると、NUMAノード1だけがMEMORYCLERK_SQLCLR
タイプに関連付けられたページを持っていることがわかります。サーバーには2つの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のメモリ使用状況の詳細については、それほど多くの情報はありません。ただし、次の2つのリソースは出発点として役立ちました。
それらから、さまざまなDMVとMSDNページを調べて(まあ、それはあまり説明していませんが、技術的には何もありません)、これらのDMVがいくらか機能するので、以下に示すクエリをまとめます。いくつかの異なるシステムでそれらを実行すると、SQLCLRメモリ割り当ては特定のmemory_node_id
に集中しているようですが、少なくともProc Cacheに関しては、他のノードに割り当てが残っています。したがって、今のところ、反対の証拠や情報がない限り、あなたが経験していることは「期待」されています。
このクエリは、基本情報を報告します。
SELECT domc.*
FROM sys.dm_os_memory_clerks domc
WHERE domc.[type] LIKE '%CLR%'
AND domc.[memory_node_id] <> 64;
特定の[type]
を1つも指定しないことで、メモリを占有する可能性のあるものがさらにいくつかあることがわかります。私が見た合計4つのタイプは次のとおりです。
64の[memory_node_id]
を除外する理由がわからない場合は、次のコマンドを実行します。
SELECT * FROM sys.dm_os_nodes;
64のnode_idがDAC(専用管理者接続)であることがわかります。
以下は、2つの重要なフィールドの合計を示します。 SQL Server 2012ではフィールドが変更されているため、使用されているSQL Serverのバージョンに適したフィールドを選択する必要があることに注意してください。
-- SQL Server 2012, 2014, and 2016:
SELECT SUM(domc.pages_kb) AS [TotalPagesKb],
SUM(domc.virtual_memory_committed_kb) AS [TotalVirtualMemoryKb]
FROM sys.dm_os_memory_clerks domc
WHERE domc.[type] LIKE '%CLR%'
AND domc.[memory_node_id] <> 64;
-- SQL Server 2005, 2008, and 2008 R2:
SELECT SUM(domc.single_pages_kb + domc.multi_pages_kb) AS [TotalPagesKb],
SUM(domc.virtual_memory_committed_kb) AS [TotalVirtualMemoryKb]
FROM sys.dm_os_memory_clerks domc
WHERE domc.[type] LIKE '%CLR%'
AND domc.[memory_node_id] <> 64;
次のクエリは、「memory_clerks」と「memory_objects」の関係を示しています。
SELECT domc.*, N' █ ' AS [ █ ], domo.*
FROM sys.dm_os_memory_clerks domc
LEFT JOIN sys.dm_os_memory_objects domo
ON domo.page_allocator_address = domc.page_allocator_address
WHERE domc.[type] LIKE N'%CLR%'
AND domc.[memory_node_id] <> 64;
次のクエリは、最初のクエリのより限定されたバージョン(および質問のクエリに似ています)ですが、SQL Server 2012ではフィールドが変更されているため、使用しているSQL Serverのバージョンに適切なものを選択する必要があります使用:
-- SQL Server 2012, 2014, and 2016:
SELECT domc.memory_node_id,
domc.[type],
domc.pages_kb,
domc.virtual_memory_committed_kb
FROM sys.dm_os_memory_clerks domc
WHERE domc.[type] LIKE '%CLR%'
AND domc.[memory_node_id] <> 64;
-- SQL Server 2005, 2008, and 2008 R2:
SELECT domc.memory_node_id,
domc.[type],
(domc.single_pages_kb + domc.multi_pages_kb) AS [pages_kb],
domc.virtual_memory_committed_kb
FROM sys.dm_os_memory_clerks domc
WHERE domc.[type] LIKE '%CLR%'
AND domc.[memory_node_id] <> 64;
UPDATE:
2つのデータベースを作成し、静的変数を使用して、各データベースに80 MBをロードすることにより、デュアルプロセッサシステムで追加のテストをいくつか行いました。 1つではなく2つのデータベースを作成し、AppDomainを1つのメモリノードに残しておく必要があるかどうかを確認しました。結果:
[virtual_memory_committed_kb]
のsys.dm_os_memory_clerks
フィールドのみでした。また、「タスクマネージャ」の「コミットサイズ」列にもこの増加が反映されています。