web-dev-qa-db-ja.com

なぜdm_os_memory_clerksは1つのNUMAノードにMEMORYCLERK_SQLCLR値を持っているのですか?

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
7
msgisme

残念ながら、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つのタイプは次のとおりです。

  • MEMORYCLERK_SQLCLR、
  • MEMORYCLERK_SQLCLRASSEMBLY
  • CACHESTORE_CLRPROC
  • CACHESTORE_CLRUDTINFO

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つのメモリノードに残しておく必要があるかどうかを確認しました。結果:

  • 両方のDB(したがって両方のAppDomain)全体で160 MBがメモリノード0に割り当てられました
  • 160 MBはすべて仮想メモリに使用され、物理メモリには使用されません。増加したのは、[virtual_memory_committed_kb]sys.dm_os_memory_clerksフィールドのみでした。また、「タスクマネージャ」の「コミットサイズ」列にもこの増加が反映されています。
3
Solomon Rutzky